La documentation dit qu'il ne faut pas utiliser la méthode available()
pour déterminer la taille d'un InputStream
. Comment puis-je 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 devrais ensuite combiner les données lues dans un tableau à un seul octet, ce qui me pose problème.
La méthode la plus simple utilisée par l’OMI consiste à utiliser Guava et ses ByteStreams
classe:
byte[] bytes = ByteStreams.toByteArray(in);
Ou pour un fichier:
byte[] bytes = Files.toByteArray(file);
Alternativement (si vous ne voulez pas utiliser Guava), vous pouvez créer un ByteArrayOutputStream
, lire à plusieurs reprises dans un tableau d'octets et écrire dans le ByteArrayOutputStream
(laissant cette poignée redimensionnant), puis appelez ByteArrayOutputStream.toByteArray()
.
Notez que cette approche fonctionne, que vous sachiez ou non la longueur de votre entrée - en supposant que vous ayez assez de mémoire, bien sûr.
N'oubliez pas que les réponses ici supposent que la longueur du fichier est inférieure ou égale à Integer.MAX_VALUE
_ (2147483647).
Si vous lisez 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();
Java 7 ajoute de nouvelles fonctionnalités au package Java.nio.file qui peuvent être utilisées pour raccourcir cet exemple de quelques lignes. 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);
Android prend en charge cette opération à partir de Api niveau 26 (8.0.0, Oreo).
Vous pouvez utiliser Apache commons-io pour cette tâche:
Reportez-vous à cette méthode :
public static byte[] readFileToByteArray(File file) throws IOException
Mise à jour:
Java 7 manière:
byte[] bytes = Files.readAllBytes(Paths.get(filename));
et s'il s'agit d'un fichier texte et que vous souhaitez le convertir en chaîne (modifiez le codage si nécessaire):
StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString()
Je crois que la longueur du tampon doit être spécifiée, car la mémoire est finie et vous risquez d'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();
Vous pouvez le lire par morceaux (byte buffer[] = new byte[2048]
) et écrivez les morceaux dans un ByteArrayOutputStream. À partir de ByteArrayOutputStream, vous pouvez récupérer le contenu sous forme d'octet [], sans avoir besoin de déterminer sa taille au préalable.
La valeur maximale pour l'index de tableau est Integer.MAX_INT - elle est d'environ 2 Go (2 ^ 31/2 147 483 647). Votre flux 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
}