Clasele ByteArrayInputStream și ByteArrayOutputStream
Pentru lucrul cu tablouri de octeți - citirea și scrierea acestora - se utilizează clasele ByteArrayInputStream și ByteArrayOutputStream.
Citirea unui tablou de octeți și clasa ByteArrayInputStream
Clasa ByteArrayInputStream reprezintă un flux de intrare care utilizează un tablou de octeți ca sursă de date. Aceasta are următorii constructori:
ByteArrayInputStream(byte[] buf)
ByteArrayInputStream(byte[] buf, int offset, int length)
Constructorii folosesc ca parametri un tablou de octeți buf, din care se face citirea, un offset relativ la începutul tabloului și numărul de caractere citite, length.
Să citim un tablou de octeți și să-l afișăm pe ecran:
import java.io.*;
public class Program {
public static void main(String[] args) {
byte[] array1 = new byte[]{1, 3, 5, 7};
ByteArrayInputStream byteStream1 = new ByteArrayInputStream(array1);
int b;
while ((b = byteStream1.read()) != -1) {
System.out.println(b);
}
String text = "Hello world!";
byte[] array2 = text.getBytes();
// citim 5 caractere
ByteArrayInputStream byteStream2 = new ByteArrayInputStream(array2, 0, 5);
int c;
while ((c = byteStream2.read()) != -1) {
System.out.println((char) c);
}
}
}
Spre deosebire de alte clase de fluxuri, nu este necesar să apelăm metoda close pentru închiderea unui obiect ByteArrayInputStream.
Scrierea unui tablou de octeți și clasa ByteArrayOutputStream
Clasa ByteArrayOutputStream reprezintă un flux de ieșire care utilizează un tablou de octeți ca loc de scriere.
Pentru a crea un obiect din această clasă, putem folosi unul dintre constructorii săi:
ByteArrayOutputStream()
ByteArrayOutputStream(int size)
Prima versiune creează un tablou de octeți cu o lungime de 32 de octeți, iar a doua versiune creează un tablou cu lungimea size.
Să analizăm utilizarea clasei:
import java.io.*;
public class Program {
public static void main(String[] args) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String text = "Hello Wolrd!";
byte[] buffer = text.getBytes();
try {
baos.write(buffer);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
// convertim tabloul de octeți într-un șir de caractere
System.out.println(baos.toString());
// obținem tabloul de octeți și îl afișăm caracter cu caracter
byte[] array = baos.toByteArray();
for (byte b : array) {
System.out.print((char) b);
}
System.out.println();
}
}
Ca și în alte fluxuri de ieșire, în clasa ByteArrayOutputStream este definită metoda write, care scrie anumite date în flux. În acest caz, scriem în flux un tablou de octeți. Acest tablou este stocat în câmpul protejat buf, care reprezintă tot un tablou de octeți (protected byte[] buf).
Deoarece metoda write poate genera o excepție, apelul său este plasat într-un bloc try..catch.
Folosind metodele toString() și toByteArray(), putem obține tabloul de octeți buf fie sub formă de text, fie direct sub forma unui tablou de octeți.
Cu ajutorul metodei writeTo, putem scrie tabloul de octeți într-un alt flux. Această metodă primește ca parametru un obiect OutputStream în care se face scrierea tabloului de octeți:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
String text = "Hello Wolrd!";
byte[] buffer = text.getBytes();
try {
baos.write(buffer);
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
try (FileOutputStream fos = new FileOutputStream("hello.txt")) {
baos.writeTo(fos);
} catch (IOException e) {
System.out.println(e.getMessage());
}
După rularea acestui program, în folderul cu programul va apărea fișierul hello.txt, care va conține șirul "Hello Wolrd!".
În concluzie, la fel ca în cazul obiectelor ByteArrayInputStream, pentru ByteArrayOutputStream nu este necesar să închidem explicit fluxul folosind metoda close.