Convertir InputStream en tableau d'octets en Java

Comment lire un InputStream entier dans un tableau d'octets?

698
demandé sur Duncan Jones 2009-08-12 11:27:22

30 réponses

vous pouvez utiliser Apache Commons IO pour gérer cette tâche et des tâches similaires.

le type IOUtils a une méthode statique pour lire un InputStream et retourner un byte[] .

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

en interne cela crée un ByteArrayOutputStream et copie les octets à la sortie, puis appelle toByteArray() . Il gère les gros fichiers en copiant les octets en blocs de 4kib.

960
répondu Rich Seller 2015-12-11 17:33:29

vous devez lire chaque octet de votre InputStream et l'écrire à un ByteArrayOutputStream . Vous pouvez ensuite récupérer le tableau byte sous-jacent en appelant toByteArray() ; par exemple

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);
}

buffer.flush();

return buffer.toByteArray();
401
répondu Adamski 2015-07-30 13:18:09

enfin, après vingt ans, il y a une solution simple sans avoir besoin d'une bibliothèque tierce, grâce à Java 9 :

InputStream is;
…
byte[] array = is.readAllBytes();

noter également les méthodes de commodité readNBytes(byte[] b, int off, int len) et transferTo(OutputStream) répondre aux besoins récurrents.

192
répondu Holger 2017-10-18 06:26:12

si vous utilisez google guava , ce sera aussi simple que:

byte[] bytes = ByteStreams.toByteArray(inputStream);
108
répondu bertie 2016-03-20 07:17:03

utilisez la méthode Java DataInputStream et sa méthode readFully (existe depuis au moins Java 1.4):

...
byte[] imgDataBa = new byte[(int)imgFile.length()];
DataInputStream dataIs = new DataInputStream(new FileInputStream(imgFile));
dataIs.readFully(imgDataBa);
...

il y a d'autres saveurs de cette méthode, mais je l'utilise tout le temps pour ce cas d'utilisation.

103
répondu dermoritz 2016-03-29 00:40:36
public static byte[] getBytesFromInputStream(InputStream is) throws IOException {
    ByteArrayOutputStream os = new ByteArrayOutputStream(); 
    byte[] buffer = new byte[0xFFFF];
    for (int len = is.read(buffer); len != -1; len = is.read(buffer)) { 
        os.write(buffer, 0, len);
    }
    return os.toByteArray();
}
34
répondu oliverkn 2018-04-28 10:21:35

comme toujours, aussi cadre de ressort (noyau de ressort depuis 3.2.2) a quelque chose pour vous: StreamUtils.copyToByteArray()

24
répondu Arne Burmeister 2017-04-18 13:59:53

avez-vous vraiment besoin de l'image en tant que byte[] ? Qu'attendez - vous exactement dans le byte[] - le contenu complet d'un fichier image, encodé dans quelque format que le fichier image est, ou les valeurs de pixels RGB?

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

Java standard API for reading (and writing) images est L'API ImageIO, que vous pouvez trouver dans le paquet 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 , pas un byte[] . Pour obtenir les données d'image, vous pouvez appeler getRaster() sur le BufferedImage . Cela vous donnera un objet Raster , qui a des méthodes pour accéder aux données des pixels (il a plusieurs méthodes getPixel() / getPixels() ).

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

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

voir aussi le tutoriel suivant: travailler avec les Images

20
répondu Jesper 2012-11-05 13:42:50

si vous ne voulez pas utiliser la bibliothèque Apache commons-io, cet extrait est tiré du soleil.misc.Classe IOUtils. Il est presque deux fois plus rapide que l'implémentation commune en utilisant des ByteBuffers:

public static byte[] readFully(InputStream is, int length, boolean readAll)
        throws IOException {
    byte[] output = {};
    if (length == -1) length = Integer.MAX_VALUE;
    int pos = 0;
    while (pos < length) {
        int bytesToRead;
        if (pos >= output.length) { // Only expand when there's no room
            bytesToRead = Math.min(length - pos, output.length + 1024);
            if (output.length < pos + bytesToRead) {
                output = Arrays.copyOf(output, pos + bytesToRead);
            }
        } else {
            bytesToRead = output.length - pos;
        }
        int cc = is.read(output, pos, bytesToRead);
        if (cc < 0) {
            if (readAll && length != Integer.MAX_VALUE) {
                throw new EOFException("Detect premature EOF");
            } else {
                if (output.length != pos) {
                    output = Arrays.copyOf(output, pos);
                }
                break;
            }
        }
        pos += cc;
    }
    return output;
}
14
répondu Kristian Kraljic 2014-09-17 14:04:14

dans le cas où quelqu'un est encore à la recherche d'une solution sans dépendance et si vous avez un fichier .

1) DataInputStream

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

2) ByteArrayOutputStream

 InputStream is = new FileInputStream(file);
 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
 int nRead;
 byte[] data = new byte[(int) file.length()];
 while ((nRead = is.read(data, 0, data.length)) != -1) {
     buffer.write(data, 0, nRead);
 }

3) RandomAccessFile

 RandomAccessFile raf = new RandomAccessFile(file, "r");
 byte[] data = new byte[(int) raf.length()];
 raf.readFully(data);
10
répondu harsh_v 2018-09-02 16:57:28

@Adamski:vous pouvez éviter tout tampon.

code copié de http://www.exampledepot.com/egs/java.io/File2ByteArray.html (Oui, il est très verbeux, mais a besoin de la moitié de la taille de la mémoire que l'autre solution.)

// Returns the contents of the file in a byte array.
public static byte[] getBytesFromFile(File file) throws IOException {
    InputStream is = new FileInputStream(file);

    // Get the size of the file
    long length = file.length();

    // You cannot create an array using a long type.
    // It needs to be an int type.
    // Before converting to an int type, check
    // to ensure that file is not larger than Integer.MAX_VALUE.
    if (length > Integer.MAX_VALUE) {
        // File is too large
    }

    // Create the byte array to hold the data
    byte[] bytes = new byte[(int)length];

    // Read in the bytes
    int offset = 0;
    int numRead = 0;
    while (offset < bytes.length
           && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
        offset += numRead;
    }

    // Ensure all the bytes have been read in
    if (offset < bytes.length) {
        throw new IOException("Could not completely read file "+file.getName());
    }

    // Close the input stream and return bytes
    is.close();
    return bytes;
}
8
répondu pihentagy 2011-06-08 08:30:49
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
while (true) {
    int r = in.read(buffer);
    if (r == -1) break;
    out.write(buffer, 0, r);
}

byte[] ret = out.toByteArray();
8
répondu YulCheney 2013-11-01 02:25:06
Input Stream is ...
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int next = in.read();
while (next > -1) {
    bos.write(next);
    next = in.read();
}
bos.flush();
byte[] result = bos.toByteArray();
bos.close();
5
répondu Aturio 2018-09-19 16:43:15

Java 9 vous donnera enfin une belle méthode:

InputStream in = ...;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
in.transferTo( bos );
byte[] bytes = bos.toByteArray();
3
répondu Christian Ullenboom 2017-02-28 20:55:23

je sais qu'il est trop tard, mais ici je pense que c'est une solution plus propre qui est plus lisible...

/**
 * method converts {@link InputStream} Object into byte[] array.
 * 
 * @param stream the {@link InputStream} Object.
 * @return the byte[] array representation of received {@link InputStream} Object.
 * @throws IOException if an error occurs.
 */
public static byte[] streamToByteArray(InputStream stream) throws IOException {

    byte[] buffer = new byte[1024];
    ByteArrayOutputStream os = new ByteArrayOutputStream();

    int line = 0;
    // read bytes from stream, and store them in buffer
    while ((line = stream.read(buffer)) != -1) {
        // Writes bytes from byte array (buffer) into output stream.
        os.write(buffer, 0, line);
    }
    stream.close();
    os.flush();
    os.close();
    return os.toByteArray();
}
2
répondu Simple-Solution 2015-06-03 11:27:16

j'ai essayé d'éditer la réponse de @numan avec un correctif pour écrire des données d'ordures mais l'édition a été rejetée. Bien que ce petit morceau de code ne soit rien de brillant, Je ne vois pas d'autre meilleure réponse. Voici ce qui a le plus de sens pour moi:

ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024]; // you can configure the buffer size
int length;

while ((length = in.read(buffer)) != -1) out.write(buffer, 0, length); //copy streams
in.close(); // call this in a finally block

byte[] result = out.toByteArray();

btw ByteArrayOutputStream ne doit pas être fermé. try / finally constructions omitted for readability

1
répondu akostadinov 2013-03-20 07:22:25

voir la InputStream.available() documentation:

il est particulièrement important de se rendre compte que vous ne devez pas utiliser ce méthode pour dimensionner un conteneur et de supposer que vous pouvez lire l'ensemble du flux sans avoir à redimensionner le conteneur. Ces appelants devrait probablement écrire tout ce qu'ils lisent à un ByteArrayOutputStream et convertir un tableau d'octets. Alternativement, si vous êtes en train de lire d'un fichier, fichier.length renvoie la longueur actuelle du fichier (bien que supposant la longueur du fichier ne peut pas changer peut être incorrect, lire un fichier est intrinsèquement laconique).

1
répondu yichouangle 2015-09-18 14:50:20

Java 7 et plus tard:

import sun.misc.IOUtils;
...
InputStream in = ...;
byte[] buf = IOUtils.readFully(in, -1, false);
1
répondu Antonio 2016-03-20 07:56:04

Java 8 way (merci à BufferedReader et Adam Bien )

private static byte[] readFully(InputStream input) throws IOException {
    try (BufferedReader buffer = new BufferedReader(new InputStreamReader(input))) {
        return buffer.lines().collect(Collectors.joining("\n")).getBytes(<charset_can_be_specified>);
    }
}

Note que cette solution essuie retour chariot ('\r') et peut être inappropriée.

1
répondu Ilya Bystrov 2017-10-03 07:32:21

l'autre cas pour obtenir le tableau correct des octets via stream, après avoir envoyé la requête au serveur et avoir attendu la réponse.

/**
         * Begin setup TCP connection to PC app
         * to open integrate connection between mobile app and pc app (or mobile app)
         */
        mSocket = new Socket(IP, port);
       // mSocket.setSoTimeout(30000);

        DataOutputStream mDos = new DataOutputStream(mSocket.getOutputStream());

        String str = "MobileRequest#" + params[0] + "#<EOF>";

        mDos.write(str.getBytes());

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        /* Since data are accepted as byte, all of them will be collected in the
        following byte array which initialised with accepted data length. */
        DataInputStream mDis = new DataInputStream(mSocket.getInputStream());
        byte[] data = new byte[mDis.available()];

        // Collecting data into byte array
        for (int i = 0; i < data.length; i++)
            data[i] = mDis.readByte();

        // Converting collected data in byte array into String.
        String RESPONSE = new String(data);
0
répondu Huy Tower 2015-07-14 08:03:17

vous faites une copie supplémentaire si vous utilisez ByteArrayOutputStream. Si vous connaissez la longueur du flux avant de commencer à le lire (par exemple, L'entrée est en fait un FileInputStream, et vous pouvez appeler file.longueur() sur le fichier, ou le InputStream est un zipfile entrée InputStream, et vous pouvez les appeler zipEntry.length ()), alors il est beaucoup mieux d'écrire directement dans le tableau byte [] -- il utilise la moitié de la mémoire, et économise du temps.

// Read the file contents into a byte[] array
byte[] buf = new byte[inputStreamLength];
int bytesRead = Math.max(0, inputStream.read(buf));

// If needed: for safety, truncate the array if the file may somehow get
// truncated during the read operation
byte[] contents = bytesRead == inputStreamLength ? buf
                  : Arrays.copyOf(buf, bytesRead);

N.B. la dernière ligne ci-dessus traite des fichiers se tronquant pendant que le flux est lu, si vous devez gérer cette possibilité, mais si le fichier obtient plus pendant que le flux est lu, le contenu dans le tableau byte[] ne sera pas allongé pour inclure le nouveau contenu du fichier, le tableau sera simplement tronqué à l'ancienne longueur inputStreamLength .

0
répondu Luke Hutchison 2015-07-30 11:26:43

j'utilise ceci.

public static byte[] toByteArray(InputStream is) throws IOException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            byte[] b = new byte[4096];
            int n = 0;
            while ((n = is.read(b)) != -1) {
                output.write(b, 0, n);
            }
            return output.toByteArray();
        } finally {
            output.close();
        }
    }
0
répondu cchcc 2016-01-13 05:05:40

C'est ma version copier-coller:

@SuppressWarnings("empty-statement")
public static byte[] inputStreamToByte(InputStream is) throws IOException {
    if (is == null) {
        return null;
    }
    // Define a size if you have an idea of it.
    ByteArrayOutputStream r = new ByteArrayOutputStream(2048);
    byte[] read = new byte[512]; // Your buffer size.
    for (int i; -1 != (i = is.read(read)); r.write(read, 0, i));
    is.close();
    return r.toByteArray();
}
0
répondu Daniel De León 2016-03-11 04:10:14

envelopper dans un flux de données si cela est hors de la table pour une raison quelconque, il suffit d'utiliser la lecture pour marteler sur elle jusqu'à ce qu'il vous donne un -1 ou le bloc entier que vous avez demandé.

public int readFully(InputStream in, byte[] data) throws IOException {
    int offset = 0;
    int bytesRead;
    boolean read = false;
    while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) {
        read = true;
        offset += bytesRead;
        if (offset >= data.length) {
            break;
        }
    }
    return (read) ? offset : -1;
}
0
répondu Tatarize 2016-12-03 08:22:24

vous pouvez essayer Cactoos :

byte[] array = new BytesOf(stream).bytes();
0
répondu yegor256 2017-08-27 12:58:40

nous voyons un certain retard pour quelques transactions AWS, tout en convertissant l'objet S3 en ByteArray.

Remarque: S3 Objet d'un document PDF (taille max est de 3 mo).

nous utilisons l'option #1 (org.apache.commons.io.IOUtils) pour convertir L'objet S3 en ByteArray. Nous avons remarqué que S3 fournit la méthode IOUtils intégrée pour convertir L'objet S3 en ByteArray, nous vous demandons de confirmer quelle est la meilleure façon de convertir L'objet S3 en ByteArray pour éviter le retard.

Option #1:

import org.apache.commons.io.IOUtils;
is = s3object.getObjectContent();
content =IOUtils.toByteArray(is);

Option #2:

import com.amazonaws.util.IOUtils;
is = s3object.getObjectContent();
content =IOUtils.toByteArray(is);

dites-moi aussi si nous avons une autre meilleure façon de convertir l'objet s3 en bytearray

0
répondu Bharathiraja S 2018-06-04 12:38:37

Voici une version optimisée, qui essaie d'éviter de copier des octets de données autant que possible:

private static byte[] loadStream (InputStream stream) throws IOException {
   int available = stream.available();
   int expectedSize = available > 0 ? available : -1;
   return loadStream(stream, expectedSize);
}

private static byte[] loadStream (InputStream stream, int expectedSize) throws IOException {
   int basicBufferSize = 0x4000;
   int initialBufferSize = (expectedSize >= 0) ? expectedSize : basicBufferSize;
   byte[] buf = new byte[initialBufferSize];
   int pos = 0;
   while (true) {
      if (pos == buf.length) {
         int readAhead = -1;
         if (pos == expectedSize) {
            readAhead = stream.read();       // test whether EOF is at expectedSize
            if (readAhead == -1) {
               return buf;
            }
         }
         int newBufferSize = Math.max(2 * buf.length, basicBufferSize);
         buf = Arrays.copyOf(buf, newBufferSize);
         if (readAhead != -1) {
            buf[pos++] = (byte)readAhead;
         }
      }
      int len = stream.read(buf, pos, buf.length - pos);
      if (len < 0) {
         return Arrays.copyOf(buf, pos);
      }
      pos += len;
   }
}
0
répondu Christian d'Heureuse 2018-08-27 00:44:32

Sous Les Codes

public static byte[] serializeObj(Object obj) throws IOException {
  ByteArrayOutputStream baOStream = new ByteArrayOutputStream();
  ObjectOutputStream objOStream = new ObjectOutputStream(baOStream);

  objOStream.writeObject(obj); 
  objOStream.flush();
  objOStream.close();
  return baOStream.toByteArray(); 
} 

ou

BufferedImage img = ...
ByteArrayOutputStream baos = new ByteArrayOutputStream(1000);
ImageIO.write(img, "jpeg", baos);
baos.flush();
byte[] result = baos.toByteArray();
baos.close();
-1
répondu firstthumb 2009-08-12 07:38:28
/*InputStream class_InputStream = null;
I am reading class from DB 
class_InputStream = rs.getBinaryStream(1);
Your Input stream could be from any source
*/
int thisLine;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((thisLine = class_InputStream.read()) != -1) {
    bos.write(thisLine);
}
bos.flush();
byte [] yourBytes = bos.toByteArray();

/*Don't forget in the finally block to close ByteArrayOutputStream & InputStream
 In my case the IS is from resultset so just closing the rs will do it*/

if (bos != null){
    bos.close();
}
-1
répondu Madhu 2011-06-02 12:45:02

Ce qui fonctionne pour moi,

if(inputStream != null){
                ByteArrayOutputStream contentStream = readSourceContent(inputStream);
                String stringContent = contentStream.toString();
                byte[] byteArr = encodeString(stringContent);
            }

readSourceContent ()

public static ByteArrayOutputStream readSourceContent(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        int nextChar;
        try {
            while ((nextChar = inputStream.read()) != -1) {
                outputStream.write(nextChar);
            }
            outputStream.flush();
        } catch (IOException e) {
            throw new IOException("Exception occurred while reading content", e);
        }

        return outputStream;
    }

encodeString ()

public static byte[] encodeString(String content) throws UnsupportedEncodingException {
        byte[] bytes;
        try {
            bytes = content.getBytes();

        } catch (UnsupportedEncodingException e) {
            String msg = ENCODING + " is unsupported encoding type";
            log.error(msg,e);
            throw new UnsupportedEncodingException(msg, e);
        }
        return bytes;
    }
-1
répondu tk_ 2015-08-26 09:56:54