Kelas ByteArrayInputStream dalam pakej java.io boleh digunakan untuk membaca tatasusunan input (daripada bait).

Untuk mencipta aliran input tatasusunan bait, kita mesti mengimport pakej java.io.ByteArrayInputStream dahulu . Selepas kami mengimport pakej, kami mempunyai dua pembina yang tersedia untuk mencipta aliran input:

ByteArrayInputStream input = new ByteArrayInputStream(arr);
ByteArrayInputStream input = new ByteArrayInputStream(arr, 2, 2);

Terdapat 4 medan di dalam kelas:

// Byte array provided by the creator of the stream
protected byte buf[];

// Index of the next character to read from the input stream's buffer
protected int pos;

// Current marked position in the stream
protected int mark = 0;

// Index is one greater than the last valid character in the input stream's buffer
protected int count;

Dan inilah pembina kami:

public ByteArrayInputStream(byte buf[]) {
    this.buf = buf;
    this.pos = 0;
    this.count = buf.length;
}

public ByteArrayInputStream(byte buf[], int offset, int length) {
    this.buf = buf;
    this.pos = offset;
    this.count = Math.min(offset + length, buf.length);
    this.mark = offset;
}

Kaedah kelas ByteArrayInputStream

Kaedah Tindakan
int baca() Membaca bait data seterusnya daripada aliran input ini.
int baca(bait b[], int off, int len) Membaca beberapa bait daripada aliran input dan menyimpannya dalam tatasusunan penimbal b .
off ialah offset ke dalam tatasusunan sasaran b .
len ialah bilangan maksimum bait untuk dibaca.
lompat panjang (panjang n) Melangkau n bait input daripada aliran input ini. Mengembalikan bilangan bait yang dilangkau (ia mungkin kurang daripada n jika kita mencapai penghujung aliran input).
int tersedia() Mengembalikan bilangan bait yang tinggal yang boleh dibaca (atau dilangkau) daripada aliran input ini.
void reset() Menetapkan semula penimbal kepada kedudukan yang ditanda. Kedudukan yang ditanda ialah 0 melainkan kedudukan lain ditandakan atau offset yang berbeza ditentukan dalam pembina.
tanda booleanSupported() Semak sama ada InputStream ini menyokong penandaan/penetapan semula. Mengembalikan benar untuk ByteArrayInputStream .
batal tutup() Tidak melakukan apa-apa.
tanda kosong(int readAheadLimit) Menetapkantandamedan sama dengan kedudukan semasa. Jika kaedah tetapan semula dipanggil, maka bacaan seterusnya akan bermula dari kedudukan itu. Parameter readAheadLimit tidak digunakan dan tidak menjejaskan tingkah laku kaedah.

Mari kita lihat dengan lebih dekat kaedah ini dan lihat cara ia berfungsi dalam amalan.

baca()

Apabila anda ingin membaca bait daripada ByteArrayInputStream seperti yang anda lakukan daripada InputStream biasa , anda boleh menggunakan kaedah read() .

public static void main(String[] args) {
   byte[] array = {1, 2, 3, 4};

   try (ByteArrayInputStream input = new ByteArrayInputStream(array)) {
       for (int i = 0; i < array.length; i++) {
           int data = input.read();
           System.out.print(data + ", ");
       }
   } catch (IOException e) {
       e.printStackTrace();
   }
}

tersedia()

Jika anda ingin menyemak sama ada terdapat sesuatu dalam penimbal anda, anda boleh memanggil kaedah available() .

public static void main(String[] args) {
   byte[] array = {1, 2, 3, 4};

   try (ByteArrayInputStream input = new ByteArrayInputStream(array)) {
       System.out.println("Bytes available for reading: " + input.available());

       input.read();
       System.out.println("Bytes available for reading " + input.available());

       input.read();
       System.out.println("Bytes available for reading " + input.available());
   } catch (IOException e) {
       e.printStackTrace();
   }
}

Kita akan melihat bahawa bilangan bait yang tersedia untuk bacaan berubah selepas setiap bacaan daripada penimbal.

Pengeluaran:

Bait tersedia untuk dibaca: 4
Bait tersedia untuk dibaca: 3
Bait tersedia untuk dibaca: 2

langkau(panjang n)

Anda boleh menggunakan kaedah langkau() untuk melangkau bilangan bait tertentu dan tidak membacanya.

public static void main(String[] args) {
   byte[] array = {1, 2, 3, 4};

   try (ByteArrayInputStream input = new ByteArrayInputStream(array)) {
       input.skip(2);

       while (input.available() != 0) {
           int data = input.read();
           System.out.print(data + ", ");
       }
   } catch (IOException e) {
       e.printStackTrace();
   }
}

Pengeluaran:

3, 4,

set semula()

Kaedah ini menetapkan semula kedudukan strim buffer kepada kedudukan yang ditanda terakhir. Ia adalah kedudukan 0 melainkan tanda yang berbeza ditetapkan.

public static void main(String[] args) {
   byte[] buf = {65, 66, 67, 68, 69};
   try (ByteArrayInputStream input = new ByteArrayInputStream(buf)) {
       System.out.println("Read: " + input.read());
       System.out.println("Read: " + input.read());
       System.out.println("Read: " + input.read());
       System.out.println("Read: " + input.read());

       System.out.println("Calling reset() method");
       input.reset();
       System.out.println("Read: " + input.read());
       System.out.println("Read: " + input.read());
   } catch (IOException e) {
       e.printStackTrace();
   }
}

Kami akan melihat bahawa memanggil kaedah reset() membawa kami ke titik permulaan strim kami.

Pengeluaran:

Baca: 65
Baca: 66
Baca: 67
Baca: 68
Kaedah reset() panggilan
Baca: 65
Baca: 66

tandakan(int readAheadLimit)

Kaedah mark() kelas ByteArrayInputStream menetapkan tanda dalaman pada kedudukan bait semasa, iaitu, sejurus selepas bait yang dibaca sebelum ini. Kaedah ini mengambil parameter yang menunjukkan bilangan bait yang boleh dibaca selepas tanda sebelum ia menjadi tidak sah. Secara lalai, jika tanda tidak ditetapkan secara eksplisit, ByteArrayInputStream menandakan kedudukan 0 atau kedudukan ofset diserahkan kepada pembinanya. Adalah penting untuk ambil perhatian bahawa tanda readAheadLimit tidak relevan untuk kelas ini.

/* Note: For this class, {@code readAheadLimit}
*  has no meaning.
*
* @since   1.1
*/
public void mark(int readAheadLimit) {
   mark = pos;
}

Berikut ialah contoh menetapkan tanda dalam ByteArrayInputStream menggunakan kaedah mark() dan reset() . Kami akan menambah panggilan ke kaedah mark() kepada contoh sebelumnya:

public static void main(String[] args) {
   byte[] buf = {65, 66, 67, 68, 69};
   try (ByteArrayInputStream input = new ByteArrayInputStream(buf)) {
       System.out.println("Read: " + input.read());
       System.out.println("Read: " + input.read());
       System.out.println("Read: " + input.read());
       input.mark(5);

       System.out.println("Read: " + input.read());
       System.out.println("Read: " + input.read());

       System.out.println("Calling reset() method");
       input.reset();

       System.out.println("Read: " + input.read());
       System.out.println("Read: " + input.read());

   } catch (IOException e) {
       e.printStackTrace();
   }
}

Kita dapat melihat bahawa kedudukan aliran semasa telah berubah.

Pengeluaran:

Baca: 65
Baca: 66
Baca: 67
Baca: 68
Baca: 69
Kaedah reset() panggilan
Baca: 68
Baca: 69

markSupported()

Kaedah markSupported() membolehkan anda menyemak sama ada tanda boleh ditetapkan. Untuk memahami dari mana nilai pulangan datang, mari pergi ke kod kaedah:

/**
* Tests if this {@code InputStream} supports mark/reset. The
* {@code markSupported} method of {@code ByteArrayInputStream}
* always returns {@code true}.
*
* @since   1.1
*/
public boolean markSupported() {
   return true;
}

Kaedah sentiasa kembali benar . Mari kita uji ini dalam amalan.

public static void main(String[] args) {
   byte[] buf = {65, 66, 67, 68, 69};
   try (ByteArrayInputStream bais = new ByteArrayInputStream(buf)) {
       boolean isMarkSupported = bais.markSupported();

       System.out.println("isMarkSupported: " + isMarkSupported);
       System.out.println("Read: " + bais.read());
       System.out.println("Read: " + bais.read());

       bais.mark(1);
       System.out.println("Read: " + bais.read());
       isMarkSupported = bais.markSupported();
       System.out.println("isMarkSupported: " + isMarkSupported);

       bais.reset();
       isMarkSupported = bais.markSupported();
       System.out.println("isMarkSupported: " + isMarkSupported);
   } catch (IOException e) {
       e.printStackTrace();
   }
}

Selepas melaksanakan kaedah mark() dan reset() , strim kami sentiasa bersedia dan menyokong tanda:

Pengeluaran:

isMarkSupported: true
Baca: 65
Baca: 66
Baca: 67
isMarkSupported: true
isMarkSupported: benar

tutup()

Dan untuk memahami kaedah rapat , mari kita lihat juga di dalamnya:

/**
* Closing a {@code ByteArrayInputStream} has no effect. The methods in
* this class can be called after the stream has been closed without
* generating an {@code IOException}.
*/
public void close() throws IOException {
}

Dokumentasi untuk kaedah tutup memberitahu kami bahawa penutupan ByteArrayInputStream tidak mempunyai kesan. Kaedah kelas ByteArrayInputStream boleh dipanggil selepas strim ditutup tanpa membuang IOException .

Apa yang boleh kita simpulkan?

Kami memerlukan ByteArrayInputStream apabila kami ingin membaca data daripada tatasusunan bait. Selalunya masuk akal untuk menggunakan kelas ini dalam kombinasi dengan kod lain yang tahu cara bekerja dengan InputStreams dan bukannya dengan sendirinya.