Octet [] vers InputStream ou OutputStream


129

J'ai une colonne blob dans ma table de base de données, pour laquelle je dois utiliser byte[]dans mon programme Java comme mappage et pour utiliser ces données, je dois la convertir en InputStreamou OutputStream. Mais je ne sais pas ce qui se passe en interne lorsque je le fais. Quelqu'un peut-il m'expliquer brièvement ce qui se passe lorsque je fais cette conversion?


2
Le titre ne devrait-il pas être "tableau d'octets ..." ou "tableau d'octets ..." ou "octet [] ..." instaed de "octet de tableau ..."?
kuester2000

Réponses:


198

Vous créez et utilisez des flux d'E / S de tableau d'octets comme suit:

byte[] source = ...;
ByteArrayInputStream bis = new ByteArrayInputStream(source);
// read bytes from bis ...

ByteArrayOutputStream bos = new ByteArrayOutputStream();
// write bytes to bos ...
byte[] sink = bos.toByteArray();

En supposant que vous utilisez un pilote JDBC qui implémente l' interface JDBC Blob standard (ce n'est pas le cas pour tous), vous pouvez également connecter un objet InputStreamou OutputStreamà un objet blob à l'aide des méthodes getBinaryStreamet 1 , et vous pouvez également obtenir et définir les octets directement.setBinaryStream

(En général, vous devez prendre les mesures appropriées pour gérer les exceptions et fermer les flux. Cependant, la fermeture biset bosdans l'exemple ci-dessus n'est pas nécessaire, car ils ne sont associés à aucune ressource externe; par exemple, des descripteurs de fichiers, des sockets, des connexions de base de données.)

1 - La setBinaryStreamméthode est vraiment un getter. Allez comprendre.


13

Je suppose que vous voulez dire que «utiliser» signifie lire, mais ce que je vais expliquer pour le cas de lecture peut être fondamentalement inversé pour le cas d'écriture.

donc vous vous retrouvez avec un octet []. cela peut représenter tout type de données pouvant nécessiter des types spéciaux de conversions (caractères, cryptées, etc.). supposons que vous vouliez écrire ces données telles quelles dans un fichier.

Tout d'abord, vous pouvez créer un ByteArrayInputStream qui est essentiellement un mécanisme pour fournir les octets à quelque chose en séquence.

vous pouvez alors créer un FileOutputStream pour le fichier que vous souhaitez créer. il existe de nombreux types de InputStreams et OutputStreams pour différentes sources de données et destinations.

Enfin, vous écririez le InputStream dans le OutputStream. dans ce cas, le tableau d'octets serait envoyé en séquence au FileOutputStream pour écriture. Pour cela, je recommande d'utiliser IOUtils

byte[] bytes = ...;//
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
FileOutputStream out = new FileOutputStream(new File(...));
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);

et à l'envers

FileInputStream in = new FileInputStream(new File(...));
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(in, out);
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
byte[] bytes = out.toByteArray();

si vous utilisez les extraits de code ci-dessus, vous devrez gérer les exceptions et je vous recommande de faire le «ferme» dans un bloc finally.


ne voulez-vous pas dire - ByteArrayOutputStream out = new ByteArrayOutputStream (); à la place ByteArrayOutputStream out = new ByteArrayInputStream ();
Avihai Marchiano

CloseQuietly devrait probablement être dans une clause finally.
JustinKSU


4

Il n'y a pas de conversion entre InputStream / OutputStream et les octets avec lesquels ils travaillent. Ils sont faits pour des données binaires, et lisent (ou écrivent) les octets un par un tels quels.

Une conversion doit avoir lieu lorsque vous souhaitez passer d'octet en caractère. Ensuite, vous devez convertir à l'aide d'un jeu de caractères. Cela se produit lorsque vous créez une chaîne ou un lecteur à partir d'octets, qui sont conçus pour les données de caractère.


1
output = new ByteArrayOutputStream();
...
input = new ByteArrayInputStream( output.toByteArray() )

0

Je me rends compte que ma réponse est bien tardive à cette question, mais je pense que la communauté aimerait une approche plus récente de cette question .


Les tampons circulaires ne résolvent pas le problème de l'OP. Dans la question telle qu'elle est écrite, l'OP a besoin de tout le contenu dans un tableau d'octets.
Stephen C

0
byte[] data = dbEntity.getBlobData();
response.getOutputStream().write();

Je pense que c'est mieux car vous avez déjà un OutputStream existant dans l'objet de réponse. pas besoin de créer un nouveau OutputStream.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.