Lecture d’un stream d’entrée binary dans un tableau à un seul octet en Java

La documentation indique qu’il ne faut pas utiliser la méthode available() pour déterminer la taille d’un InputStream . Comment lire le contenu entier d’un InputStream dans un tableau d’octets?

 InputStream in; //assuming already present byte[] data = new byte[in.available()]; in.read(data);//now data is filled with the whole content of the InputStream 

Je pouvais lire plusieurs fois dans un tampon de taille fixe, mais je devrai combiner les données lues dans un tableau à un seul octet, ce qui est un problème pour moi.

L’approche la plus simple consiste à utiliser Guava et sa classe ByteStreams :

 byte[] bytes = ByteStreams.toByteArray(in); 

Ou pour un fichier:

 byte[] bytes = Files.toByteArray(file); 

Alternativement (si vous ne souhaitez pas utiliser Guava), vous pouvez créer un ByteArrayOutputStream , lire plusieurs fois dans un tableau d’octets et écrire dans le ByteArrayOutputStream (en laissant cette ByteArrayOutputStream redimensionner), puis appeler ByteArrayOutputStream.toByteArray() .

Notez que cette approche fonctionne si vous pouvez indiquer la longueur de votre entrée ou non – en supposant que vous ayez suffisamment de mémoire, bien sûr.

Si vous lisez à partir d’un fichier, vous pouvez faire quelque chose comme ceci:

  File file = new File("myFile"); byte[] fileData = new byte[(int) file.length()]; DataInputStream dis = new DataInputStream(new FileInputStream(file)); dis.readFully(fileData); dis.close(); 

MISE À JOUR (31 mai 2014):

Java 7 ajoute de nouvelles fonctionnalités dans le package java.nio.file qui peuvent être utilisées pour raccourcir cet exemple. Voir la méthode readAllBytes () dans la classe java.nio.file.Files . Voici un court exemple:

 import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; // ... Path p = FileSystems.getDefault().getPath("", "myFile"); byte [] fileData = Files.readAllBytes(p); 

Notez que, au moment d’écrire ces lignes, l’API Android ne supporte pas cela (ou beaucoup de choses dans Java 7).

Vous pouvez utiliser Apache commons-io pour cette tâche:

Reportez-vous à cette méthode :

 public static byte[] readFileToByteArray(File file) throws IOException 

Mettre à jour:

Façon Java 7 :

 byte[] bytes = Files.readAllBytes(Paths.get(filename)); 

et s’il s’agit d’un fichier texte que vous souhaitez convertir en chaîne (modifiez le codage si nécessaire):

 StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toSsortingng() 

Vous pouvez le lire par blocs ( byte buffer[] = new byte[2048] ) et écrire les morceaux dans un ByteArrayOutputStream. À partir de ByteArrayOutputStream, vous pouvez récupérer le contenu sous la forme d’un octet [], sans avoir à déterminer auparavant sa taille.

Je crois que la longueur de la mémoire tampon doit être spécifiée, car la mémoire est finie et vous pouvez en manquer

Exemple:

 InputStream in = new FileInputStream(strFileName); long length = fileFileName.length(); if (length > Integer.MAX_VALUE) { throw new IOException("File is too large!"); } byte[] bytes = new byte[(int) length]; int offset = 0; int numRead = 0; while (offset < bytes.length && (numRead = in.read(bytes, offset, bytes.length - offset)) >= 0) { offset += numRead; } if (offset < bytes.length) { throw new IOException("Could not completely read file " + fileFileName.getName()); } in.close(); 

La valeur maximale de l’index du tableau est Integer.MAX_INT – elle est d’environ 2 Go (2 ^ 31/2 147 483 647). Votre stream d’entrée peut être supérieur à 2 Go, vous devez donc traiter les données en morceaux, désolé.

  InputStream is; final byte[] buffer = new byte[512 * 1024 * 1024]; // 512Mb while(true) { final int read = is.read(buffer); if ( read < 0 ) { break; } // do processing }