Bagaimana saya mengonversi a java.io.File
ke a byte[]
?
Bagaimana saya mengonversi a java.io.File
ke a byte[]
?
Jawaban:
Itu tergantung pada apa arti terbaik untuk Anda. Produktivitas bijaksana, jangan menemukan kembali roda dan menggunakan Apache Commons. Yang ada di sini IOUtils.toByteArray(InputStream input)
.
File
ke byte[]
? Saya menggunakan Java6 jadi saya tidak bisa menggunakan metode NIO :(
Dari JDK 7 Anda dapat menggunakan Files.readAllBytes(Path)
.
Contoh:
import java.io.File;
import java.nio.file.Files;
File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());
Sejak JDK 7 - satu liner:
byte[] array = Files.readAllBytes(Paths.get("/path/to/file"));
Tidak diperlukan dependensi eksternal.
import java.nio.file.Files;
dan import java.nio.file.Paths;
jika Anda belum melakukannya.
import java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Dokumentasi untuk Java 8: http://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html
Pada dasarnya Anda harus membacanya di memori. Buka file, alokasikan array, dan baca konten dari file ke dalam array.
Cara paling sederhana adalah sesuatu yang mirip dengan ini:
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();
}
Ini memiliki beberapa penyalinan konten file yang tidak perlu (sebenarnya data disalin tiga kali: dari file ke buffer
, dari buffer
ke ByteArrayOutputStream
, dari ByteArrayOutputStream
ke array yang dihasilkan aktual).
Anda juga perlu memastikan Anda membaca dalam memori hanya file hingga ukuran tertentu (ini biasanya tergantung aplikasi) :-).
Anda juga perlu memperlakukan IOException
fungsi di luar.
Cara lain adalah ini:
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;
}
Ini tidak memiliki penyalinan yang tidak perlu.
FileTooBigException
adalah pengecualian aplikasi khusus. The MAX_FILE_SIZE
konstan adalah parameter aplikasi.
Untuk file besar, Anda mungkin harus berpikir algoritma pemrosesan aliran atau menggunakan pemetaan memori (lihat java.nio
).
Seperti kata seseorang, Utilitas File Commons Apache mungkin memiliki apa yang Anda cari
public static byte[] readFileToByteArray(File file) throws IOException
Contoh penggunaan ( 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);
...
}
}
Anda dapat menggunakan api NIO juga untuk melakukannya. Saya bisa melakukan ini dengan kode ini selama ukuran total file (dalam byte) akan cocok dengan 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();
}
}
Saya pikir ini sangat cepat karena menggunakan MappedByteBuffer.
Jika Anda tidak memiliki Java 8, dan setuju dengan saya bahwa memasukkan pustaka besar untuk menghindari penulisan beberapa baris kode adalah ide yang buruk:
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();
}
Penelepon bertanggung jawab untuk menutup aliran.
// 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!");
apa yang harus kita lakukan ketika file terlalu besar? Apakah ada contoh tentang hal itu?
Cara sederhana untuk melakukannya:
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);
Cara termudah untuk membaca byte dari file
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);
}
}
}
.*
, itu dianggap praktik buruk.
Guava memiliki Files.toByteArray () untuk menawarkan Anda. Ini memiliki beberapa keunggulan:
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);
Menggunakan pendekatan yang sama dengan jawaban komunitas wiki, tetapi lebih bersih dan kompilasi di luar kotak (pendekatan yang lebih disukai jika Anda tidak ingin mengimpor Apache Commons libs, misalnya di 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();
}
Saya percaya ini adalah cara termudah:
org.apache.commons.io.FileUtils.readFileToByteArray(file);
ReadFully Membaca b. Panjang byte dari file ini ke dalam array byte, mulai dari penunjuk file saat ini. Metode ini membaca berulang kali dari file hingga jumlah byte yang diminta dibaca. Metode ini memblokir hingga jumlah byte yang diminta dibaca, akhir aliran terdeteksi, atau pengecualian dilemparkan.
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Jika Anda ingin membaca byte ke buffer byte yang dialokasikan sebelumnya, jawaban ini dapat membantu.
Tebakan pertama Anda mungkin akan digunakan InputStream read(byte[])
. Namun, metode ini memiliki kelemahan yang membuatnya sulit digunakan: tidak ada jaminan bahwa array akan benar-benar diisi, bahkan jika tidak ada EOF yang ditemui.
Sebaliknya, lihatlah DataInputStream readFully(byte[])
. Ini adalah pembungkus untuk aliran input, dan tidak memiliki masalah yang disebutkan di atas. Selain itu, metode ini melempar ketika EOF ditemui. Jauh lebih bagus.
Tidak hanya cara berikut mengonversi java.io.File ke byte [], saya juga menemukan itu menjadi cara tercepat untuk membaca dalam sebuah file, ketika menguji berbagai metode membaca file Java yang berbeda satu sama lain:
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);
}
}
}
Izinkan saya menambahkan solusi lain tanpa menggunakan perpustakaan pihak ketiga. Ini menggunakan kembali pola penanganan pengecualian yang diusulkan oleh Scott ( tautan ). Dan saya memindahkan bagian yang jelek ke dalam pesan terpisah (saya akan bersembunyi di beberapa kelas 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);
}
}
}
Cara lain untuk membaca byte dari file
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"
Coba ini :
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);
}
Di JDK8
Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();