web-dev-qa-db-fra.com

Comment charger une ressource classpath dans un tableau d'octets?

je sais comment obtenir le flux d'entrée pour une ressource de chemin de classe donnée, lu à partir du flux d'entrée jusqu'à ce que j'atteigne la fin, mais il ressemble à un problème très courant, et je me demande s'il y a une API que je ne connais pas, ou une bibliothèque qui rendrait les choses aussi simples que

byte[] data = ResourceUtils.getResourceAsBytes("/assets/myAsset.bin")

ou

byte[] data = StreamUtils.readStreamToEnd(myInputStream)

par exemple!

27
Samuel Rossille

Jetez un œil à Google goyave ByteStreams.toByteArray(INPUTSTREAM), c'est peut-être ce que vous voulez.

31
user1335794

Jetez un oeil à Apache IOUtils - il a un tas de méthodes pour travailler avec les flux

16

Implémentation native de Java 9:

byte[] data = this.getClass().getClassLoader().getResourceAsStream("/assets/myAsset.bin").readAllBytes();
11
Marek Gregor

Bien que je sois d'accord avec Andrew Thompson, voici une implémentation native qui fonctionne depuis Java 7 et utilise l'API NIO:

byte[] data = Files.readAllBytes(Paths.get(this.getClass().getClassLoader().getResource("/assets/myAsset.bin").toURI()));
9
ltlBeBoy

J'utilise généralement les deux approches suivantes pour convertir Resource en tableau byte[].

1 - approche

Ce dont vous avez besoin est d'appeler d'abord getInputStream() sur Resource objet, puis de le passer à la méthode convertStreamToByteArray comme ci-dessous ....

InputStream stream = resource.getInputStream();
long size = resource.getFile().lenght();

byte[] byteArr = convertStreamToByteArray(stream, size);

public byte[] convertStreamToByteArray(InputStream stream, long size) throws IOException {

    // check to ensure that file size is not larger than Integer.MAX_VALUE.
    if (size > Integer.MAX_VALUE) {
        return new byte[0];
    }

    byte[] buffer = new byte[(int)size];
    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 - approche

Comme l'a suggéré Konstantin V. Salikhov, vous pouvez utiliser org.Apache.commons.io.IOUtils Et appeler sa méthode IOUtils.toByteArray(stream)static et lui passer InputStream objet comme celui-ci ...

byte[] byteArr = IOUtils.toByteArray(stream);

Note - Je pensais juste mentionner que sous le capot toByteArray(...) vérifie que la taille du fichier n'est pas supérieure à Integer.MAX_VALUE, Vous n'avez donc pas à vérifier ce.

9
Simple-Solution

Généralement Java accepteront un InputStream. Dans la majorité des cas, je recommanderais de passer le flux directement à la méthode qui nous intéresse.

Beaucoup de ces mêmes méthodes accepteront également un URL (par exemple obtenu à partir de getResource(String)). Cela peut parfois être mieux, car une variété de méthodes nécessitera un repositionnable InputStream et il y a des moments où le flux renvoyé par getResourceAsStream(String) --- not sera repositionnable.

4
Andrew Thompson