Lecture d'un flux d'entrée binaire dans un tableau d'octets unique en Java
la documentation dit qu'il ne faut pas utiliser available()
méthode pour déterminer la taille d'un InputStream
. Comment puis-je lire tout le contenu 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 pourrais lire plusieurs fois dans un tampon de taille fixe, mais ensuite, je vais devoir combiner les données que j'ai lues dans un tableau d'octets unique, ce qui est un problème pour moi.
6 réponses
L'approche la plus simple IMO est d'utiliser Goyave et son ByteStreams
catégorie:
byte[] bytes = ByteStreams.toByteArray(in);
Ou pour un fichier:
byte[] bytes = Files.toByteArray(file);
Sinon (si vous ne voulez pas utiliser de Goyave), vous pouvez créer un ByteArrayOutputStream
, et à plusieurs reprises lire dans un tableau d'octets et écrire dans le ByteArrayOutputStream
(laisser cette poignée Redimensionner), puis appeler ByteArrayOutputStream.toByteArray()
.
notez que cette approche fonctionne si vous pouvez dire la longueur de votre entrer ou ne pas entrer - en supposant que vous avez assez 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 java.nio.paquet de fichiers qui peut être utilisé pour raccourcir quelques lignes de cet exemple. Voir le readAllBytes () méthode java.nio.fichier.Les fichiers classe. 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 de la rédaction de cet article, L'API Android ne soutenez ceci (ou beaucoup de n'importe quoi 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
mise à Jour:
Java 7:
byte[] bytes = Files.readAllBytes(Paths.get(filename));
et si c'est un fichier texte et que vous voulez le convertir en chaîne (changez l'encodage au besoin):
StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString()
Vous pouvez le lire par morceaux (byte buffer[] = new byte[2048]
) et écrire les morceaux à un ByteArrayOutputStream. De ByteArrayOutputStream vous pouvez récupérer le contenu comme un byte [], sans avoir besoin de déterminer sa taille au préalable.
je crois longueur de la mémoire tampon doit être spécifié, comme la mémoire est fini et vous pouvez exécuter de
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 Max pour l'index de tableau est entier.MAX_INT - c'est environ 2 Go (2^31 / 2 147 483 647). Votre flux d'entrée peut être plus grand que 2 Go, donc vous devez 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
}