Wie konvertiere ich a java.io.File
in a byte[]
?
Wie konvertiere ich a java.io.File
in a byte[]
?
Antworten:
Es kommt darauf an, was für Sie am besten bedeutet. In Bezug auf die Produktivität sollten Sie das Rad nicht neu erfinden und Apache Commons verwenden. Welches ist hier IOUtils.toByteArray(InputStream input)
.
File
zu lesen byte[]
? Ich benutze Java6, daher kann ich die NIO-Methoden nicht verwenden :(
Ab JDK 7 können Sie verwenden Files.readAllBytes(Path)
.
Beispiel:
import java.io.File;
import java.nio.file.Files;
File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());
Seit JDK 7 - ein Liner:
byte[] array = Files.readAllBytes(Paths.get("/path/to/file"));
Keine externen Abhängigkeiten erforderlich.
import java.nio.file.Files;
und import java.nio.file.Paths;
wenn Sie noch nicht.
import java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Dokumentation für Java 8: http://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html
Grundsätzlich muss man es im Speicher lesen. Öffnen Sie die Datei, ordnen Sie das Array zu und lesen Sie den Inhalt der Datei in das Array.
Der einfachste Weg ist ähnlich:
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();
}
Dies führt zu unnötigem Kopieren des Dateiinhalts (tatsächlich werden die Daten dreimal kopiert: von Datei zu buffer
, von buffer
zu ByteArrayOutputStream
, von ByteArrayOutputStream
zu dem tatsächlich resultierenden Array).
Sie müssen auch sicherstellen, dass Sie nur Dateien bis zu einer bestimmten Größe im Speicher lesen (dies ist normalerweise anwendungsabhängig) :-).
Sie müssen auch die IOException
Außenseite der Funktion behandeln.
Ein anderer Weg ist folgender:
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;
}
Dies hat kein unnötiges Kopieren.
FileTooBigException
ist eine benutzerdefinierte Anwendungsausnahme. Die MAX_FILE_SIZE
Konstante ist ein Anwendungsparameter.
Für große Dateien sollten Sie wahrscheinlich einen Stream-Verarbeitungsalgorithmus in Betracht ziehen oder die Speicherzuordnung verwenden (siehe java.nio
).
Wie jemand sagte, haben Apache Commons File Utils möglicherweise das, wonach Sie suchen
public static byte[] readFileToByteArray(File file) throws IOException
Beispiel use ( 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);
...
}
}
Sie können dazu auch die NIO-API verwenden. Ich könnte dies mit diesem Code tun, solange die gesamte Dateigröße (in Bytes) in ein int passt.
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();
}
}
Ich denke, es ist sehr schnell, da es MappedByteBuffer verwendet.
Wenn Sie nicht über Java 8 verfügen und mir zustimmen, ist es eine schlechte Idee, eine umfangreiche Bibliothek einzuschließen, um das Schreiben einiger Codezeilen zu vermeiden:
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();
}
Der Anrufer ist für das Schließen des Streams verantwortlich.
// 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!");
Was sollen wir tun, wenn die Datei zu groß ist? Gibt es auch ein Beispiel dafür?
Einfache Möglichkeit:
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);
Einfachster Weg zum Lesen von Bytes aus einer Datei
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);
}
}
}
.*
, es wird als schlechte Praxis angesehen.
Guava hat Files.toByteArray () zu bieten. Es hat mehrere Vorteile:
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);
Verwenden Sie denselben Ansatz wie die Antwort des Community-Wikis, aber sauberer und sofort kompilierbarer Ansatz (bevorzugter Ansatz, wenn Sie keine Apache Commons-Bibliotheken importieren möchten, z. B. unter 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();
}
Ich glaube, das ist der einfachste Weg:
org.apache.commons.io.FileUtils.readFileToByteArray(file);
ReadFully Liest b.Länge Bytes aus dieser Datei in das Byte-Array, beginnend mit dem aktuellen Dateizeiger. Diese Methode liest wiederholt aus der Datei, bis die angeforderte Anzahl von Bytes gelesen wurde. Diese Methode blockiert, bis die angeforderte Anzahl von Bytes gelesen, das Ende des Streams erkannt oder eine Ausnahme ausgelöst wurde.
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Wenn Sie Bytes in einen vorab zugewiesenen Bytepuffer einlesen möchten, kann diese Antwort hilfreich sein.
Ihre erste Vermutung wäre wahrscheinlich zu verwenden InputStream read(byte[])
. Diese Methode weist jedoch einen Fehler auf, der die Verwendung unangemessen schwierig macht: Es gibt keine Garantie dafür, dass das Array tatsächlich vollständig gefüllt ist, selbst wenn kein EOF auftritt.
Schauen Sie sich stattdessen an DataInputStream readFully(byte[])
. Dies ist ein Wrapper für Eingabestreams und weist das oben genannte Problem nicht auf. Darüber hinaus wird diese Methode ausgelöst, wenn EOF auftritt. Viel schöner.
Die folgende Methode konvertiert eine java.io.File nicht nur in ein Byte [], sondern hat auch festgestellt, dass dies die schnellste Methode zum Einlesen einer Datei ist, wenn viele verschiedene Lesemethoden für Java-Dateien gegeneinander getestet werden :
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);
}
}
}
Lassen Sie mich eine weitere Lösung hinzufügen, ohne Bibliotheken von Drittanbietern zu verwenden. Es wird ein von Scott vorgeschlagenes Ausnahmebehandlungsmuster ( Link ) wiederverwendet . Und ich habe den hässlichen Teil in eine separate Nachricht verschoben (ich würde mich in einer FileUtils-Klasse verstecken;))
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);
}
}
}
Eine andere Möglichkeit, Bytes aus Dateien zu lesen
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"
Versuche dies :
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);
}
In JDK8
Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();