Comment convertir un java.io.File
en un byte[]
?
Comment convertir un java.io.File
en un byte[]
?
Réponses:
Cela dépend de ce que signifie le mieux pour vous. Côté productivité, ne réinventez pas la roue et utilisez Apache Commons. C'est ici IOUtils.toByteArray(InputStream input)
.
File
à byte[]
? J'utilise Java6, je ne peux donc pas utiliser les méthodes NIO :(
Depuis 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());
Depuis JDK 7 - une doublure:
byte[] array = Files.readAllBytes(Paths.get("/path/to/file"));
Aucune dépendance externe requise.
import java.nio.file.Files;
et import java.nio.file.Paths;
si vous ne l'avez pas déjà fait.
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
Fondamentalement, vous devez le lire en mémoire. Ouvrez le fichier, allouez le tableau et lisez le contenu du fichier dans le tableau.
La manière la plus simple est similaire à 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 a une copie inutile du contenu du fichier (en fait, les données sont copiées trois fois: du fichier à buffer
, de buffer
à ByteArrayOutputStream
, de ByteArrayOutputStream
au tableau résultant réel).
Vous devez également vous assurer de ne lire en mémoire que les fichiers jusqu'à une certaine taille (cela dépend généralement de l'application) :-).
Vous devez également traiter l' IOException
extérieur 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 MAX_FILE_SIZE
constante est un paramètre d'application.
Pour les gros fichiers, vous devriez probablement penser à un algorithme de traitement de flux ou utiliser le mappage de mémoire (voir java.nio
).
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);
...
}
}
Vous pouvez également utiliser l'API NIO pour le faire. Je pourrais faire cela avec ce code tant que la taille totale du fichier (en octets) tiendrait dans 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.
Si vous n'avez pas Java 8, et convenez avec moi qu'inclure une bibliothèque massive 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.
// 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;
}
throw new IOException("File is too large!");
que devons-nous faire lorsque le fichier est trop volumineux? Y a-t-il également un exemple à ce sujet?
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);
Manière la plus simple 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);
}
}
}
.*
, c'est considéré comme une mauvaise pratique.
Guava a Files.toByteArray () à vous offrir. Il présente plusieurs avantages:
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);
En utilisant la même approche que la réponse du wiki de la communauté, mais plus propre et compilant hors de la boîte (approche préférée si vous ne voulez pas importer des 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();
}
Je crois que c'est la manière la plus simple:
org.apache.commons.io.FileUtils.readFileToByteArray(file);
ReadFully Lit les octets b.length de ce fichier dans le tableau d'octets, en commençant par le pointeur de fichier actuel. Cette méthode lit à plusieurs reprises à partir du fichier jusqu'à ce que le nombre d'octets demandé soit lu. Cette méthode se bloque 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);
Si vous souhaitez lire des octets dans un tampon d'octets pré-alloué, cette réponse peut vous aider.
Votre première supposition serait probablement d'utiliser InputStream read(byte[])
. Cependant, cette méthode a un défaut qui la rend excessivement difficile à utiliser: il n'y a aucune garantie que la baie sera réellement complètement remplie, même si aucun EOF n'est rencontré.
Jetez plutôt un œil à DataInputStream readFully(byte[])
. Ceci est un wrapper pour les flux d'entrée et n'a pas le problème mentionné ci-dessus. En outre, cette méthode se déclenche lorsque EOF est rencontré. Beaucoup mieux.
Non seulement la manière suivante convertit un fichier java.io.File en octet [], mais je l'ai également trouvé comme le moyen le plus rapide de lire un fichier, lors du test de nombreuses méthodes de lecture de fichiers Java les unes contre les autres:
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);
}
}
}
Permettez-moi d'ajouter une autre solution sans utiliser de bibliothèques tierces. Il réutilise un modèle de gestion des exceptions qui a été proposé par Scott ( lien ). Et j'ai déplacé la partie laide dans un message séparé (je me 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;
}
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);
}
}
}
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();
}
}
//The file that you wanna convert into byte[]
File file=new File("/storage/0CE2-EA3D/DCIM/Camera/VID_20190822_205931.mp4");
FileInputStream fileInputStream=new FileInputStream(file);
byte[] data=new byte[(int) file.length()];
BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
bufferedInputStream.read(data,0,data.length);
//Now the bytes of the file are contain in the "byte[] data"
Essaye ça :
import sun.misc.IOUtils;
import java.io.IOException;
try {
String path="";
InputStream inputStream=new FileInputStream(path);
byte[] data=IOUtils.readFully(inputStream,-1,false);
}
catch (IOException e) {
System.out.println(e);
}
Dans JDK8
Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();