web-dev-qa-db-fra.com

Lecture d’un flux d’entrée binaire dans un tableau d’octets sur Java

La documentation dit qu'il ne faut pas utiliser la méthode available() pour déterminer la taille d'un InputStream. Comment puis-je lire le contenu entier 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 pouvais lire plusieurs fois dans un tampon de taille fixe, mais je devrais ensuite combiner les données lues dans un tableau à un seul octet, ce qui me pose problème.

46
Qiang Li

La méthode la plus simple utilisée par l’OMI consiste à utiliser Guava et ses ByteStreams classe:

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

Ou pour un fichier:

byte[] bytes = Files.toByteArray(file);

Alternativement (si vous ne voulez pas utiliser Guava), vous pouvez créer un ByteArrayOutputStream , lire à plusieurs reprises dans un tableau d'octets et écrire dans le ByteArrayOutputStream (laissant cette poignée redimensionnant), puis appelez ByteArrayOutputStream.toByteArray() .

Notez que cette approche fonctionne, que vous sachiez ou non la longueur de votre entrée - en supposant que vous ayez assez de mémoire, bien sûr.

62
Jon Skeet

N'oubliez pas que les réponses ici supposent que la longueur du fichier est inférieure ou égale à Integer.MAX_VALUE _ (2147483647).

Si vous lisez 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 au package Java.nio.file qui peuvent être utilisées pour raccourcir cet exemple de quelques lignes. Voir la méthode readAllBytes () dans la classe Java.nio.file.Files . 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);

Android prend en charge cette opération à partir de Api niveau 26 (8.0.0, Oreo).

56
James K Polk

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 manière:

byte[] bytes = Files.readAllBytes(Paths.get(filename));

et s'il s'agit d'un fichier texte et que vous souhaitez le convertir en chaîne (modifiez le codage si nécessaire):

StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString()
9
Andrey

Je crois que la longueur du tampon doit être spécifiée, car la mémoire est finie et vous risquez d'en manquer

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();
5
JAM

Vous pouvez le lire par morceaux (byte buffer[] = new byte[2048]) et écrivez les morceaux dans un ByteArrayOutputStream. À partir de ByteArrayOutputStream, vous pouvez récupérer le contenu sous forme d'octet [], sans avoir besoin de déterminer sa taille au préalable.

5
SJuan76

La valeur maximale pour l'index de tableau est Integer.MAX_INT - elle est d'environ 2 Go (2 ^ 31/2 147 483 647). Votre flux d'entrée peut être supérieur à 2 Go, vous devez donc 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 
        }
3
ya_pulser