web-dev-qa-db-fra.com

Fichier en octet [] en Java

Comment convertir un Java.io.File en byte[]?

629
Ben Noland

Cela dépend de ce que signifie le mieux pour vous. Sur le plan de la productivité, ne réinventez pas la roue et utilisez Apache Commons. Ce qui est ici IOUtils.toByteArray(InputStream input) .

419
svachon

A partir de JDK 7, vous pouvez utiliser Files.readAllBytes(Path) .

Exemple:

import Java.io.File;
import Java.nio.file.Files;

File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());
1123
Alan
import Java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);

Documentation pour Java 8: http://docs.Oracle.com/javase/8/docs/api/Java/io/RandomAccessFile.html

156
Dmitry Mitskevich

Depuis le JDK 7 - une doublure:

byte[] array = Files.readAllBytes(new File("/path/to/file").toPath());

Aucune dépendance externe nécessaire.

142
Paulius Matulionis

Fondamentalement, vous devez le lire en mémoire. Ouvrez le fichier, allouez le tableau et lisez le contenu du fichier dans le tableau. 

Le moyen le plus simple ressemble à ceci: 

public byte[] read(File file) throws IOException, FileTooBigException {
    if (file.length() > MAX_FILE_SIZE) {
        throw new FileTooBigException(file);
    }
    ByteArrayOutputStream ous = null;
    InputStream ios = null;
    try {
        byte[] buffer = new byte[4096];
        ous = new ByteArrayOutputStream();
        ios = new FileInputStream(file);
        int read = 0;
        while ((read = ios.read(buffer)) != -1) {
            ous.write(buffer, 0, read);
        }
    }finally {
        try {
            if (ous != null)
                ous.close();
        } catch (IOException e) {
        }

        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
        }
    }
    return ous.toByteArray();
}

Cela entraîne une copie inutile du contenu du fichier (en fait, les données sont copiées trois fois: de fichier à buffer, de buffer à ByteArrayOutputStream, de ByteArrayOutputStream au tableau résultant réel.

Vous devez également vous assurer de ne lire dans la mémoire que les fichiers d’une certaine taille (cela dépend généralement de l’application) :-). 

Vous devez également traiter la IOException en dehors de la fonction.

Une autre façon est la suivante: 

public byte[] read(File file) throws IOException, FileTooBigException {
    if (file.length() > MAX_FILE_SIZE) {
        throw new FileTooBigException(file);
    }

    byte[] buffer = new byte[(int) file.length()];
    InputStream ios = null;
    try {
        ios = new FileInputStream(file);
        if (ios.read(buffer) == -1) {
            throw new IOException(
                    "EOF reached while trying to read the whole file");
        }
    } finally {
        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
        }
    }
    return buffer;
}

Cela n'a pas de copie inutile.

FileTooBigException est une exception d'application personnalisée. La constante MAX_FILE_SIZE est un paramètre d'application.

Pour les gros fichiers, pensez probablement à un algorithme de traitement de flux ou utilisez le mappage de la mémoire (voir Java.nio). 

76
Mihai Toader

Comme quelqu'un l'a dit, Apache Commons File Utils pourrait avoir ce que vous cherchez

public static byte[] readFileToByteArray(File file) throws IOException

Exemple d'utilisation (Program.Java):

import org.Apache.commons.io.FileUtils;
public class Program {
    public static void main(String[] args) throws IOException {
        File file = new File(args[0]);  // assume args[0] is the path to file
        byte[] data = FileUtils.readFileToByteArray(file);
        ...
    }
}
68
Tom

Vous pouvez également utiliser l’API NIO pour le faire. Je pourrais le faire avec ce code tant que la taille totale du fichier (en octets) correspondrait à un int.

File f = new File("c:\\wscp.script");
FileInputStream fin = null;
FileChannel ch = null;
try {
    fin = new FileInputStream(f);
    ch = fin.getChannel();
    int size = (int) ch.size();
    MappedByteBuffer buf = ch.map(MapMode.READ_ONLY, 0, size);
    byte[] bytes = new byte[size];
    buf.get(bytes);

} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} finally {
    try {
        if (fin != null) {
            fin.close();
        }
        if (ch != null) {
            ch.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Je pense que c'est très rapide depuis son utilisation de MappedByteBuffer.

21
Amit
// Returns the contents of the file in a byte array.
    public static byte[] getBytesFromFile(File file) throws IOException {        
        // 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
            throw new IOException("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;

        InputStream is = new FileInputStream(file);
        try {
            while (offset < bytes.length
                   && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
                offset += numRead;
            }
        } finally {
            is.close();
        }

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

Si vous ne possédez pas Java 8 et acceptez avec moi que l'inclusion d'une bibliothèque volumineuse pour éviter d'écrire quelques lignes de code est une mauvaise idée:

public static byte[] readBytes(InputStream inputStream) throws IOException {
    byte[] b = new byte[1024];
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    int c;
    while ((c = inputStream.read(b)) != -1) {
        os.write(b, 0, c);
    }
    return os.toByteArray();
}

L'appelant est responsable de la fermeture du flux.

18
Jeffrey Blattman

Un moyen simple de le faire:

File fff = new File("/path/to/file");
FileInputStream fileInputStream = new FileInputStream(fff);

// int byteLength = fff.length(); 

// In Android the result of file.length() is long
long byteLength = fff.length(); // byte count of the file-content

byte[] filecontent = new byte[(int) byteLength];
fileInputStream.read(filecontent, 0, (int) byteLength);
15
Sudip Bhandari

Le plus simple moyen de lire des octets à partir d'un fichier

import Java.io.*;

class ReadBytesFromFile {
    public static void main(String args[]) throws Exception {
        // getBytes from anyWhere
        // I'm getting byte array from File
        File file = null;
        FileInputStream fileStream = new FileInputStream(file = new File("ByteArrayInputStreamClass.Java"));

        // Instantiate array
        byte[] arr = new byte[(int) file.length()];

        // read All bytes of File stream
        fileStream.read(arr, 0, arr.length);

        for (int X : arr) {
            System.out.print((char) X);
        }
    }
}
12
Muhammad Sadiq

Guava a Files.toByteArray () à vous offrir. Il présente plusieurs avantages:

  1. Il couvre le cas où les fichiers indiquent une longueur de 0 mais ont toujours un contenu
  2. Il est hautement optimisé. Vous obtenez une exception OutOfMemoryException si vous essayez de lire un gros fichier avant d’essayer même de le charger. (Grâce à une utilisation intelligente de file.length ())
  3. Vous n'avez pas à réinventer la roue.
11
jontejj

Utiliser la même approche que la réponse du wiki de la communauté, mais plus propre et compiler immédiatement (approche recommandée si vous ne souhaitez pas importer les bibliothèques Apache Commons, par exemple sur Android):

public static byte[] getFileBytes(File file) throws IOException {
    ByteArrayOutputStream ous = null;
    InputStream ios = null;
    try {
        byte[] buffer = new byte[4096];
        ous = new ByteArrayOutputStream();
        ios = new FileInputStream(file);
        int read = 0;
        while ((read = ios.read(buffer)) != -1)
            ous.write(buffer, 0, read);
    } finally {
        try {
            if (ous != null)
                ous.close();
        } catch (IOException e) {
            // swallow, since not that important
        }
        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
            // swallow, since not that important
        }
    }
    return ous.toByteArray();
}
9
manmal
import Java.io.File;
import Java.nio.file.Files;
import Java.nio.file.Path;

File file = getYourFile();
Path path = file.toPath();
byte[] data = Files.readAllBytes(path);
9
BlondCode

Je crois que c'est le moyen le plus simple:

org.Apache.commons.io.FileUtils.readFileToByteArray(file);
7
Cristian Tetic

ReadFully Lit les octets b.length de ce fichier dans le tableau d'octets, en commençant par le pointeur du fichier actuel. Cette méthode lit le fichier à plusieurs reprises jusqu'à ce que le nombre d'octets demandé soit lu. Cette méthode est bloquée jusqu'à ce que le nombre d'octets demandé soit lu, que la fin du flux soit détectée ou qu'une exception soit levée.

RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
5
Tarun M

Si vous souhaitez lire des octets dans un tampon d'octets pré-alloué, cette réponse peut vous aider.

Votre première hypothèse serait probablement d’utiliser InputStream read(byte[]) . Cependant, cette méthode a une faille qui la rend excessivement difficile à utiliser: rien ne garantit que le tableau sera réellement rempli, même si aucun EOF n'est rencontré.

Au lieu de cela, jetez un oeil à DataInputStream readFully(byte[]) . Il s'agit d'un wrapper pour les flux d'entrée et ne présente pas le problème mentionné ci-dessus. De plus, cette méthode est levée lorsque EOF est rencontré. Beaucoup mieux.

3
Laurens Holst

Permettez-moi d'ajouter une autre solution sans utiliser de bibliothèques tierces. Il réutilise un modèle de traitement des exceptions proposé par Scott ( link ). Et j'ai déplacé la partie laide dans un message séparé (je cacherais dans une classe FileUtils;))

public void someMethod() {
    final byte[] buffer = read(new File("test.txt"));
}

private byte[] read(final File file) {
    if (file.isDirectory())
        throw new RuntimeException("Unsupported operation, file "
                + file.getAbsolutePath() + " is a directory");
    if (file.length() > Integer.MAX_VALUE)
        throw new RuntimeException("Unsupported operation, file "
                + file.getAbsolutePath() + " is too big");

    Throwable pending = null;
    FileInputStream in = null;
    final byte buffer[] = new byte[(int) file.length()];
    try {
        in = new FileInputStream(file);
        in.read(buffer);
    } catch (Exception e) {
        pending = new RuntimeException("Exception occured on reading file "
                + file.getAbsolutePath(), e);
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (Exception e) {
                if (pending == null) {
                    pending = new RuntimeException(
                        "Exception occured on closing file" 
                             + file.getAbsolutePath(), e);
                }
            }
        }
        if (pending != null) {
            throw new RuntimeException(pending);
        }
    }
    return buffer;
}
3
Andreas_D
public static byte[] readBytes(InputStream inputStream) throws IOException {
    byte[] buffer = new byte[32 * 1024];
    int bufferSize = 0;
    for (;;) {
        int read = inputStream.read(buffer, bufferSize, buffer.length - bufferSize);
        if (read == -1) {
            return Arrays.copyOf(buffer, bufferSize);
        }
        bufferSize += read;
        if (bufferSize == buffer.length) {
            buffer = Arrays.copyOf(buffer, bufferSize * 2);
        }
    }
}
2
mazatwork

Une autre façon de lire les octets du fichier

Reader reader = null;
    try {
        reader = new FileReader(file);
        char buf[] = new char[8192];
        int len;
        StringBuilder s = new StringBuilder();
        while ((len = reader.read(buf)) >= 0) {
            s.append(buf, 0, len);
            byte[] byteArray = s.toString().getBytes();
        }
    } catch(FileNotFoundException ex) {
    } catch(IOException e) {
    }
    finally {
        if (reader != null) {
            reader.close();
        }
    }
1
Muhammad Aamir Ali

Essaye ça :

    try
    {
        String path="";

        InputStream inputStream=new FileInputStream(path);

        byte[] data=IOUtils.readFully(inputStream,-1,false);

    }
    catch (Exception e)
    {

    }

N'oubliez pas de "importer Sun.misc.IOUtils;"

0
Maifee Ul Asad

Non seulement la manière suivante convertit un fichier Java.io.File en un octet [], mais j’ai également trouvé que c’était le moyen le plus rapide de lire un fichier, lorsqu’on testait de nombreuses méthodes de lecture de fichiers différentes :

Java.nio.file.Files.readAllBytes ()

import Java.io.File;
import Java.io.IOException;
import Java.nio.file.Files;

public class ReadFile_Files_ReadAllBytes {
  public static void main(String [] pArgs) throws IOException {
    String fileName = "c:\\temp\\sample-10KB.txt";
    File file = new File(fileName);

    byte [] fileBytes = Files.readAllBytes(file.toPath());
    char singleChar;
    for(byte b : fileBytes) {
      singleChar = (char) b;
      System.out.print(singleChar);
    }
  }
}
0
gomisha