Convertir InputStream de tableau d'octets en Java
Comment puis-je lire la totalité d'une InputStream
dans un tableau d'octets?
- Voir l'inverse: byte[] pour InputStream ici: stackoverflow.com/questions/2091454/...
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser Apache Commons IO pour gérer ce type de tâches.
La
IOUtils
type possède une méthode statique pour lire unInputStream
et retourner unbyte[]
.En interne, ce qui crée un
ByteArrayOutputStream
et copie les octets à la sortie, puis appelletoByteArray()
. Il gère de gros fichiers par copier les octets dans des blocs de 4KiB.FastArrayList
ou leur soft & la faiblesse des Cartes de référence et de revenir me dire comment "bien testé" cette bibliothèque est. C'est un tas d'orduresInputStream is;
byte[] filedata=ByteStreams.toByteArray(is);
go and have a look at Apache commons stuff like FastArrayList or their soft & weak reference Maps and come back to tell me how "well-tested" this library is
... c'est comme dire "le goût de ces choux de bruxelles, et me dire à quel point ces tomates sont". Si j'ajoute ces tomates de mon plat, le goût de tester, à l'aimer et tout le monde apparemment, il aime trop, alors que dois-je soin de les choux de bruxelles à partir de la même épicerie sont ka-ka ?IOUtils.toByteArray(InputStream)
seulement des copies dans des blocs de 4 KO, pas de 4MB. Dans IOUtils.java la taille de bloc est défini commeprivate static final int DEFAULT_BUFFER_SIZE = 1024 * 4
.Vous avez besoin de lire chaque octet à partir de votre
InputStream
et de l'écrire sur unByteArrayOutputStream
. Vous pouvez ensuite récupérer les sous-jacents le tableau d'octets en appelanttoByteArray()
; par exemple,byte[] data = new byte[16384]; is.read(data, 0, data.length)); return data;
buffer.write(data, 0, nRead);
, cela ne signifie pas que dans la deuxième itération de la mémoire tampon de données sera remplacé car le décalage est de nouveau à partir du début (0)?Enfin, après une vingtaine d'années, il y a une solution simple, sans la nécessité pour une 3ème partie de la bibliothèque, grâce à Java 9:
Note également la commodité des méthodes
readNBytes(byte[] b, int off, int len)
ettransferTo(OutputStream)
abordant les besoins récurrents.Utiliser la vanille de Java
DataInputStream
et sesreadFully
Méthode (qui n'existe au moins depuis Java 1.4):Il y a quelques autres saveurs de cette méthode, mais j'en utilise tout le temps pour ce cas d'utilisation.
DataInputStream
primaire est utilisé pour lire des types primaires (Longs, courts métrages, Chars...) à partir d'un flux, afin que nous puissions voir cette utilisation, une utilisation abusive de la classe.InputStream.read
.readFully
- la différence est dans la façon dont ils gèrent le flux se terminant avant le nombre d'octets demandés a été lu.read
se ferme tôt et renvoie le nombre d'octets lus,readFully
déclenche une exception.readFully
boucles en interne jusqu'à ce qu'il a besoin d'octets. C'est beaucoup plus pratique que d'utiliserread
où vous devez écrire la boucle de vous-même. Donc je dirais que c'est mieux. J'ai juste eu exactement ce cas de m'arriver avec un GZIPInputStream où une lecture appel serait de retour avec seulement une fraction de la nécessaire octets et readFully les lire tous. Et dans les deux cas, je savais que la longueur des données à lire à partir du flux.Si vous arrive d'utiliser google goyave, ça va être aussi simple que :
ByteStreams
est annoté avec@Beta
Comme toujours, aussi Spring framework (printemps-core depuis 3.2.2) a quelque chose pour vous:
StreamUtils.copyToByteArray()
Avez-vous vraiment besoin de l'image de
byte[]
? Exactement ce que vous attendez dans lebyte[]
- le contenu complet d'un fichier d'image, encodé dans le format que le fichier image est en, ou des valeurs de pixels RVB?D'autres réponses ici vous montrer comment lire un fichier dans un
byte[]
. Votrebyte[]
contiendra le contenu exact du fichier, et vous auriez besoin de le décoder à faire n'importe quoi avec les données de l'image.Java de l'API standard pour la lecture (et l'écriture) d'images est le ImageIO API, que vous pouvez trouver dans le package
javax.imageio
. Vous pouvez lire une image à partir d'un fichier, avec une seule ligne de code:Cela vous donnera une
BufferedImage
, pas unbyte[]
. Pour obtenir les données d'image, vous pouvez appelergetRaster()
sur leBufferedImage
. Cela vous donnera uneRaster
objet, qui a des méthodes pour accéder aux données de pixels (il a plusieursgetPixel()
/getPixels()
méthodes).La recherche de la documentation de l'API pour
javax.imageio.ImageIO
,java.awt.image.BufferedImage
,java.awt.image.Raster
etc.ImageIO prend en charge un certain nombre de formats d'image par défaut: JPEG, PNG, BMP, WBMP, GIF. Il est possible d'ajouter le support pour d'autres formats (vous auriez besoin d'un plug-in qui implémente l'ImageIO service provider interface).
Voir aussi le tutoriel suivant: Travailler avec des Images
Sûr solution (avec une capacité d'
close
flux correctement):Java 9+ version:
Java 8 version:
Kotlin version (lorsque Java 9+ n'est pas accessible):
Pour éviter imbriquée
use
voir ici.Si vous ne souhaitez pas utiliser l'Apache commons-io de la bibliothèque, cet extrait est tiré du soleil.misc.IOUtils classe. C'est près de deux fois plus rapide que la mise en commun à l'aide de ByteBuffers:
Au cas où quelqu'un est toujours à la recherche d'une solution sans une dépendance et Si vous avez un fichier.
@Adamski: Vous pouvez éviter tampon entièrement.
Code copié à partir de http://www.exampledepot.com/egs/java.io/File2ByteArray.html (Oui, c'est très détaillé, mais les besoins de la moitié de la taille de la mémoire comme de l'autre solution.)
is.close()
sioffset < bytes.length
ou laInputStream
ne sera pas fermé si cette exception est levée.InputStream
dans unBufferedInputStream
avant que le code permettrait de réduire les OS des appels et d'atténuer les performances des inconvénients de manière significative, ce code sera toujours inutile manuel de la copie de travail à partir d'un tampon à l'autre.Java 9 vous donnera enfin une belle méthode:
InputStram.readAllBytes()
qui est one-liner?Je sais que c'est trop tard, mais ici je pense que est solution de nettoyage qui est plus lisible...
Java 8 (grâce à BufferedReader et Adam Bien)
Note que cette solution lingettes retour chariot ('\r') et peut être inapproprié.
String
. L'OP demandebyte[]
.\r
qui pourrait être un problème. Cette méthode convertit les octets de caractères et de retour à nouveau (en utilisant le jeu de caractères par défaut pour InputStreamReader). Tous les octets qui ne sont pas valides dans le codage de caractères par défaut (par exemple, -1 pour l'UTF-8 sur Linux) sera endommagée et peut-être même changer le nombre d'octets.J'ai essayé de modifier @numan de répondre avec un correctif pour l'écriture des ordures données, mais cette édition a été rejetée. Tout ce petit morceau de code est rien de génial, je ne vois pas d'autre meilleure réponse. Voici ce qui fait le plus de sens pour moi:
btw ByteArrayOutputStream n'a pas besoin d'être fermé. try/finally constructions omis pour des raisons de lisibilité
Voir le
InputStream.available()
documentation:L'autre cas, à obtenir de bons tableau d'octets via des flux, après envoyer une requête au serveur et attend la réponse.
Vous êtes en train de faire une copie supplémentaire si vous utilisez ByteArrayOutputStream. Si vous connaissez la longueur du cours d'eau avant de commencer à le lire (par exemple, l'InputStream est en fait un FileInputStream, et vous pouvez les appeler de fichier.longueur() sur le fichier, ou le InputStream est un zipfile entrée InputStream, et vous pouvez les appeler zipEntry.longueur()), alors il est de loin préférable d'écrire directement dans le byte[] tableau -- il utilise la moitié de la mémoire, et permet de gagner du temps.
N. B. la dernière ligne ci-dessus traite de fichiers tronqués alors que le flux est en cours de lecture, si vous avez besoin pour gérer cette possibilité, mais si le fichier est plus alors que le flux est en cours de lecture, le contenu dans le byte[] tableau ne sera pas allongée pour inclure le nouveau contenu du fichier, le tableau sera simplement tronqué à l'ancienne longueur inputStreamLength.
Je l'utilise.
C'est mon copier-coller de la version:
Java 7 et les versions ultérieures:
sun.misc.IOUtils
n'est pas “Java 7”. C'est une propriété, la mise en œuvre spécifique de la classe qui ne peut pas être présents dans d'autres JRE implémentations et peut disparaître sans aucun avertissement dans une des prochaines versions.De l'envelopper dans un DataInputStream si c'est hors de la table pour une raison quelconque, il suffit d'utiliser lire de marteau jusqu'à ce qu'il vous donne un -1 ou la totalité du bloc que vous avez demandé.
Vous pouvez essayer Cactoos:
Nous voyons un peu de retard pour quelques AWS transaction, lors de la conversion S3 objet ByteArray.
Remarque: S3 Objet d'un document PDF (taille max est de 3 mo).
Nous sommes à l'aide de l'option #1 (org.apache.commons.io.IOUtils) pour convertir le S3 objet ByteArray. Nous avons remarqué S3 fournir les inbuild IOUtils méthode pour convertir le S3 objet ByteArray, nous vous demandons de confirmer quel est le meilleur moyen de convertir le S3 objet ByteArray pour éviter le retard.
Option #1:
Option #2:
Aussi laissez-moi savoir si nous avons de meilleur moyen pour convertir les s3 objet bytearray
Ici est une version optimisée, qui tente d'éviter le copier-octets de données, autant que possible:
Cela fonctionne pour moi,
readSourceContent()
encodeString()
String
puis àbyte[]
(qui pourrait gâcher, avec des données binaires)?ByteArrayOutputStream
a.toByteArray()
: docs.oracle.com/javase/7/docs/api/java/io/...Ci-Dessous Les Codes
OU