Lecture d'un flux d'entrée binaire dans un tableau d'octets unique en Java

la documentation dit qu'il ne faut pas utiliser available() méthode pour déterminer la taille d'un InputStream. Comment puis-je lire tout le contenu 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 pourrais lire plusieurs fois dans un tampon de taille fixe, mais ensuite, je vais devoir combiner les données que j'ai lues dans un tableau d'octets unique, ce qui est un problème pour moi.

43
demandé sur Palec 2011-08-31 01:50:25

6 réponses

L'approche la plus simple IMO est d'utiliser Goyave et son ByteStreams catégorie:

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

Ou pour un fichier:

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

Sinon (si vous ne voulez pas utiliser de Goyave), vous pouvez créer un ByteArrayOutputStream, et à plusieurs reprises lire dans un tableau d'octets et écrire dans le ByteArrayOutputStream (laisser cette poignée Redimensionner), puis appeler ByteArrayOutputStream.toByteArray().

notez que cette approche fonctionne si vous pouvez dire la longueur de votre entrer ou ne pas entrer - en supposant que vous avez assez de mémoire, bien sûr.

61
répondu Jon Skeet 2018-05-20 22:46:33

Si vous lisez à partir d'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 dans le java.nio.paquet de fichiers qui peut être utilisé pour raccourcir quelques lignes de cet exemple. Voir le readAllBytes () méthode java.nio.fichier.Les fichiers classe. 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);

notez que, au moment de la rédaction de cet article, L'API Android ne soutenez ceci (ou beaucoup de n'importe quoi dans Java 7).

51
répondu James K Polk 2014-05-31 13:35:46

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:

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

et si c'est un fichier texte et que vous voulez le convertir en chaîne (changez l'encodage au besoin):

StandardCharsets.UTF_8.decode(ByteBuffer.wrap(bytes)).toString()
9
répondu Andrey 2013-10-02 13:17:35

Vous pouvez le lire par morceaux (byte buffer[] = new byte[2048]) et écrire les morceaux à un ByteArrayOutputStream. De ByteArrayOutputStream vous pouvez récupérer le contenu comme un byte [], sans avoir besoin de déterminer sa taille au préalable.

5
répondu SJuan76 2011-08-30 22:02:14

je crois longueur de la mémoire tampon doit être spécifié, comme la mémoire est fini et vous pouvez exécuter de

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();
4
répondu JAM 2011-08-30 21:52:58

La valeur Max pour l'index de tableau est entier.MAX_INT - c'est environ 2 Go (2^31 / 2 147 483 647). Votre flux d'entrée peut être plus grand que 2 Go, donc vous devez 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
répondu ya_pulser 2013-11-12 11:17:01