Klassen ByteArrayInputStream i paketet java.io kan användas för att läsa en inmatningsmatris (med byte).

För att skapa en indataström för bytearray måste vi först importera java.io.ByteArrayInputStream -paketet. Efter att vi har importerat paketet har vi två konstruktorer tillgängliga för att skapa en indataström:

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

Det finns 4 fält i klassen:

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

Och här är våra konstruktörer:

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

Metoder för klassen ByteArrayInputStream

Metod Handling
int read() Läser nästa byte med data från denna ingångsström.
int read(byte b[], int off, int len) Läser flera byte från ingångsströmmen och lagrar dem i buffertmatris b .
off är en offset till målarray b .
len är det maximala antalet byte att läsa.
långt hoppa (långt n) Hoppar över n byte indata från denna ingångsström. Returnerar antalet byte som hoppats över (det kan vara mindre än n om vi når slutet av ingångsströmmen).
int tillgänglig() Returnerar antalet återstående byte som kan läsas (eller hoppas över) från denna ingångsström.
void reset() Återställer bufferten till den markerade positionen. Den markerade positionen är 0 om inte en annan position är markerad eller en annan offset specificeras i konstruktorn.
boolean markSupported() Kontrollerar om denna InputStream stöder markering/återställning. Returnerar sant för ByteArrayInputStream .
void close() Gör ingenting.
void mark (int readAheadLimit) Ställer inmärkefält lika med den aktuella positionen. Om återställningsmetoden anropas, kommer efterföljande läsning att börja från den positionen. Parametern readAheadLimit används inte och påverkar inte metoden.

Låt oss titta närmare på dessa metoder och se hur de fungerar i praktiken.

läsa()

När du vill läsa bytes från en ByteArrayInputStream precis som du skulle göra från en vanlig InputStream , kan du använda metoden 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();
   }
}

tillgängliga()

Om du vill kontrollera om det finns något i din buffert kan du anropa metoden 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();
   }
}

Vi kommer att se att antalet byte tillgängliga för läsning ändras efter varje läsning från bufferten.

Produktion:

Byte tillgängliga för läsning: 4
Byte tillgängliga för läsning: 3
Byte tillgängliga för läsning: 2

hoppa över (långt n)

Du kan använda skip() -metoden för att hoppa över ett visst antal byte och inte läsa dem.

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

Produktion:

3, 4,

återställa()

Denna metod återställer den buffrade strömmens position till den senast markerade positionen. Det är position 0 om inte en annan markering är inställd.

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

Vi kommer att se att anrop av reset() -metoden tar oss till vår ströms startpunkt.

Produktion:

Läs: 65
Läs: 66
Läs: 67
Läs: 68
Anropar reset()-metoden
Läs: 65
Läs: 66

mark(int readAheadLimit)

Mark () -metoden för klassen ByteArrayInputStream sätter det interna märket vid den aktuella bytepositionen, det vill säga omedelbart efter den tidigare lästa byten. Den här metoden tar en parameter som indikerar hur många byte som kan läsas efter markeringen innan den blir ogiltig. Som standard, om markeringen inte är inställd explicit, markerar en ByteArrayInputStream position 0 eller positionen för offset som skickas till dess konstruktor. Det är viktigt att notera att markeringen readAheadLimit är irrelevant för denna klass.

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

Här är ett exempel på hur du ställer in ett märke i en ByteArrayInputStream med dess mark()- och reset()- metoder. Vi kommer att lägga till ett anrop till mark() -metoden i föregående exempel:

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

Vi kan se att den nuvarande strömmens position har ändrats.

Produktion:

Läs: 65
Läs: 66
Läs: 67
Läs: 68
Läs: 69
Anropar reset()-metoden
Läs: 68
Läs: 69

markSupported()

Metoden markSupported () låter dig kontrollera om ett märke kan ställas in. För att förstå var returvärdet kommer ifrån, låt oss gå till metodens kod:

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

Metoden returnerar alltid sant . Låt oss testa detta i praktiken.

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

Efter att ha kört metoderna mark() och reset() är vår stream alltid redo och stöder märken:

Produktion:

isMarkSupported: true
Läst: 65
Läst: 66
Läst: 67
isMarkSupported: true
isMarkSupported: true

stänga()

Och för att förstå närmetoden , låt oss också ta en titt inuti den:

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

Dokumentationen för stängningsmetoden berättar att det inte har någon effekt att stänga en ByteArrayInputStream . Klassmetoderna ByteArrayInputStream kan anropas efter att strömmen stängts utan att kasta en IOException .

Vad kan vi dra slutsatsen?

Vi behöver en ByteArrayInputStream när vi vill läsa data från en byte-array. Det brukar vara vettigt att använda den här klassen i kombination med annan kod som vet hur man fungerar med InputStreams snarare än ensam.