1016 votes

Convertir InputStream en tableau d'octets en Java

Comment puis-je lire un InputStream dans un tableau d'octets ?

18 votes

Voir l'inverse : byte[] to InputStream ici : stackoverflow.com/questions/2091454/

1286voto

Rich Seller Points 46052

Vous pouvez utiliser Apache Commons IO pour gérer cette tâche et d'autres similaires.

En IOUtils possède une méthode statique pour lire un InputStream et renvoyer un byte[] .

InputStream is;
byte[] bytes = IOUtils.toByteArray(is);

En interne, cela crée un ByteArrayOutputStream et copie les octets sur la sortie, puis appelle toByteArray() . Il traite les gros fichiers en copiant les octets par blocs de 4KiB.

227 votes

Pour l'envie d'écrire 4 lignes de code, vous pensez que l'importation d'une dépendance tierce partie vaut la peine ?

242 votes

S'il existe une bibliothèque qui répond à cette exigence, qui traite le traitement des gros fichiers et qui est bien testée, la question est sûrement de savoir pourquoi je l'écrirais moi-même. Le jar ne fait que 107 Ko et si vous avez besoin d'une méthode, il est probable que vous en utilisiez d'autres.

268 votes

@oxbow_lakes : considérant la quantité stupéfiante de mauvais implémentations de cette fonctionnalité que j'ai vues dans ma vie de développeur, je pense que oui c'est très Cela vaut vraiment la peine de dépendre de l'extérieur pour bien faire les choses.

498voto

Adamski Points 29884

Vous devez lire chaque octet de votre InputStream et l'écrire dans un ByteArrayOutputStream .

Vous pouvez ensuite récupérer le tableau d'octets sous-jacent en appelant toByteArray() :

InputStream is = ...
ByteArrayOutputStream buffer = new ByteArrayOutputStream();

int nRead;
byte[] data = new byte[16384];

while ((nRead = is.read(data, 0, data.length)) != -1) {
  buffer.write(data, 0, nRead);
}

return buffer.toByteArray();

23 votes

Qu'en est-il de la taille des byte[] nouvellement créés. Pourquoi est-elle de 16384 ? Comment puis-je déterminer la taille exacte ? Merci beaucoup.

6 votes

16384 est un choix assez arbitraire bien que j'ai tendance à favoriser les puissances de 2 pour augmenter les chances que le tableau s'aligne sur les limites des mots. La réponse de pihentagy montre comment vous pouvez éviter d'utiliser un tampon intermédiaire, mais plutôt allouer un tableau de la taille correcte. A moins que vous n'ayez affaire à de gros fichiers, je préfère personnellement le code ci-dessus, qui est plus élégant et peut être utilisé pour les InputStreams où le nombre d'octets à lire n'est pas connu à l'avance.

0 votes

@Adamski La création d'un tableau d'octets n'est-elle pas beaucoup plus grande que ce que vous attendez des données dans le flux, ne gaspille-t-elle pas la mémoire ?

143voto

dermoritz Points 1465

Utilisez la fonction DataInputStream et son readFully Méthode (existe depuis au moins Java 1.4) :

...
byte[] bytes = new byte[(int) file.length()];
DataInputStream dis = new DataInputStream(new FileInputStream(file));
dis.readFully(bytes);
...

Il existe d'autres variantes de cette méthode, mais je l'utilise tout le temps pour ce cas d'utilisation.

51 votes

+1 pour l'utilisation des bibliothèques standard au lieu d'une dépendance d'une tierce partie. Malheureusement, cela ne fonctionne pas pour moi car je ne connais pas la longueur du flux en amont.

2 votes

Qu'est-ce que imgFile ? Cela ne peut pas être un InputStream, qui était censé être l'entrée de cette méthode.

4 votes

@janus c'est un "fichier". cette méthode ne fonctionne que si vous connaissez la longueur du fichier ou le nombre d'octets à lire.

140voto

bertie Points 4186

Si vous utilisez Google Guava il suffira d'utiliser ByteStreams :

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

9 votes

ByteStreams est annoté avec @Beta

19voto

Jesper Points 65733

Avez-vous vraiment besoin de l'image comme byte[] ? Qu'attendez-vous exactement de la byte[] - le contenu complet d'un fichier d'image, codé dans n'importe quel format du fichier d'image, ou les valeurs de pixels RVB ?

D'autres réponses ici vous montrent comment lire un fichier dans une byte[] . Votre byte[] contiendra le contenu exact du fichier, et vous devrez le décoder pour faire quoi que ce soit avec les données de l'image.

L'API standard de Java pour lire (et écrire) des images est l'API ImageIO, que vous trouverez dans le paquetage javax.imageio . Vous pouvez lire une image à partir d'un fichier avec une seule ligne de code :

BufferedImage image = ImageIO.read(new File("image.jpg"));

Cela vous donnera un BufferedImage et non un byte[] . Pour accéder aux données de l'image, vous pouvez appeler getRaster() sur le BufferedImage . Cela vous donnera un Raster qui dispose de méthodes pour accéder aux données des pixels (il a plusieurs objets getPixel() / getPixels() méthodes).

Consultez la documentation de l'API pour javax.imageio.ImageIO , java.awt.image.BufferedImage , java.awt.image.Raster etc.

ImageIO supporte par défaut un certain nombre de formats d'images : JPEG, PNG, BMP, WBMP et GIF. Il est possible d'ajouter le support d'autres formats (vous aurez besoin d'un plug-in qui implémente l'interface du fournisseur de services ImageIO).

Voir aussi le tutoriel suivant : Travailler avec des images

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X