A java.io csomag ByteArrayInputStream osztálya használható egy (byte-os) bemeneti tömb olvasására.

Bájttömb bemeneti adatfolyam létrehozásához először importálni kell a java.io.ByteArrayInputStream csomagot. A csomag importálása után két konstruktor áll rendelkezésünkre a bemeneti adatfolyam létrehozásához:


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

Az osztályon belül 4 mező található:


// 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;
    

És itt vannak a kivitelezőink:


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;
}
    

A ByteArrayInputStream osztály módszerei

Módszer Akció
int read() Beolvassa a következő adatbájtot ebből a bemeneti adatfolyamból.
int read(byte b[], int off, int len) Több bájtot beolvas a bemeneti adatfolyamból, és a b puffertömbben tárolja .
Az off egy eltolás a b céltömbbe .
A len az olvasandó bájtok maximális száma.
hosszú kihagyás (hosszú n) Kihagy n bájtnyi bemenetet ebből a bemeneti adatfolyamból. Az átugrott bájtok számát adja vissza (ez kisebb lehet n-nél, ha elérjük a bemeneti adatfolyam végét).
int elérhető() Az ebből a bemeneti adatfolyamból kiolvasható (vagy átugorható) fennmaradó bájtok számát adja vissza.
void reset() Visszaállítja a puffert a megjelölt pozícióba. A megjelölt pozíció 0, kivéve, ha másik pozíciót jelöltünk meg, vagy más eltolás nincs megadva a konstruktorban.
logikai markSupported() Ellenőrzi, hogy ez az InputStream támogatja-e a jelölést/visszaállítást. Igaz értéket ad vissza a ByteArrayInputStream esetén .
void close() Nem csinál semmit.
üres jel (int readAheadLimit) Beállítja aMarkmező egyenlő az aktuális pozícióval. Ha a reset módszert hívják, akkor a következő kiolvasás ebből a pozícióból indul. A readAheadLimit paraméter nem használatos, és nincs hatással a metódus viselkedésére.

Nézzük meg közelebbről ezeket a módszereket, és nézzük meg, hogyan működnek a gyakorlatban.

olvas()

Ha egy ByteArrayInputStream- ből bájtokat szeretne olvasni, ugyanúgy, mint egy közönséges InputStream- ből , használhatja a read() metódust.


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();
   }
}
    

elérhető()

Ha ellenőrizni szeretné, hogy van-e valami a pufferben, akkor meghívhatja az available() metódust.


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();
   }
}
    

Látni fogjuk, hogy az olvasáshoz rendelkezésre álló bájtok száma a pufferből történő minden egyes olvasás után változik.

Kimenet:

Olvasható bájtok: 4 olvasható
bájt: 3
olvasható bájt: 2

kihagyás (hosszú n)

A skip() metódussal átugorhat egy bizonyos számú bájtot, és nem olvassa el.


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();
   }
}
    

Kimenet:

3, 4,

Visszaállítás()

Ez a módszer visszaállítja a pufferelt adatfolyam pozícióját az utoljára megjelölt pozícióra. Ez a 0 pozíció, hacsak nincs beállítva más jel.


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();
   }
}
    

Látni fogjuk, hogy a reset() metódus meghívása az adatfolyamunk kiindulópontjához vezet.

Kimenet:

Olvasás: 65
Olvasás: 66
Olvasás: 67
Olvasás: 68
Reset() metódus hívása
Olvasás: 65
Olvasás: 66

mark(int readAheadLimit)

A ByteArrayInputStream osztály mark() metódusa a belső jelölést az aktuális bájtpozícióra állítja be, vagyis közvetlenül az előzőleg beolvasott bájt után. Ez a módszer egy olyan paramétert vesz fel, amely azt jelzi, hogy hány bájt olvasható a jelölés után, mielőtt az adatfolyam érvénytelenné válik. Alapértelmezés szerint, ha a jelölés nincs kifejezetten beállítva, a ByteArrayInputStream a 0 pozíciót vagy a konstruktorának átadott eltolás pozícióját jelöli meg. Fontos megjegyezni, hogy a readAheadLimit jelzés irreleváns ennél az osztálynál.


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

Íme egy példa a jelölés beállítására egy ByteArrayInputStreamben a mark() és reset() metódusok használatával . Hozzáadjuk a mark() metódus hívását az előző példához:


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();
   }
}
    

Láthatjuk, hogy az aktuális adatfolyam helyzete megváltozott.

Kimenet:

Olvasás: 65
Olvasás: 66
Olvasás: 67
Olvasás: 68
Olvasás: 69
Reset() metódus hívása
Olvasás: 68
Olvasás: 69

markSupported()

A markSupported() metódus lehetővé teszi annak ellenőrzését, hogy beállítható-e jelölés. Ahhoz, hogy megértsük, honnan származik a visszatérési érték, menjünk a metódus kódjához:


/**
* 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;
}
    

A metódus mindig igazat ad vissza . Teszteljük ezt a gyakorlatban.


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();
   }
}
    

A mark() és reset() metódusok végrehajtása után a streamünk mindig készen áll, és támogatja a jelöléseket:

Kimenet:

isMarkSupported: true
Olvasás: 65
Olvasás: 66
Olvasás: 67
isMarkSupported: true
isMarkSupported: igaz

Bezárás()

A bezárási módszer megértéséhez pedig vessünk egy pillantást a belsejébe is:


/**
* 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 {
}
    

A bezárási módszer dokumentációja azt mondja, hogy a ByteArrayInputStream bezárása nincs hatással. A ByteArrayInputStream osztálymetódusok az adatfolyam bezárása után hívhatók meg IOException nélkül .

Mire következtethetünk?

Szükségünk van egy ByteArrayInputStream-re , ha adatokat szeretnénk olvasni egy bájttömbből. Általában célszerű ezt az osztályt más kóddal kombinálva használni, amely tudja, hogyan kell dolgozni az InputStreams- szel , nem pedig önmagában.