Файл в байт [] в Java
Как мне конвертировать java.io.File
к byte[]
?
28 ответов
Это зависит от того, что лучше для вас значит. Производительность мудрая, не изобретайте велосипед и используйте Apache Commons. Который здесь IOUtils.toByteArray(InputStream input)
,
С JDK 7 вы можете использовать Files.readAllBytes(Path)
,
Пример:
import java.io.File;
import java.nio.file.Files;
File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());
Начиная с JDK 7 - один лайнер:
byte[] array = Files.readAllBytes(new File("/path/to/file").toPath());
Внешние зависимости не нужны.
import java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Документация для Java 8: http://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html
В основном вы должны прочитать это в памяти. Откройте файл, выделите массив и прочитайте содержимое файла в массив.
Самый простой способ - это что-то похожее на это:
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();
}
При этом происходит ненужное копирование содержимого файла (фактически данные копируются три раза: из файла в buffer
, от buffer
в ByteArrayOutputStream
, от ByteArrayOutputStream
к фактическому результирующему массиву).
Вам также необходимо убедиться, что вы читаете в памяти только файлы определенного размера (обычно это зависит от приложения):-).
Вы также должны относиться к IOException
вне функции.
Другой способ заключается в следующем:
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;
}
Это не имеет ненужного копирования.
FileTooBigException
исключение пользовательского приложения. MAX_FILE_SIZE
константа - это параметры приложения.
Для больших файлов вы должны подумать об алгоритме обработки потока или использовать отображение памяти (см. java.nio
).
Как кто-то сказал, Apache Commons File Utils может иметь то, что вы ищете
public static byte[] readFileToByteArray(File file) throws IOException
Пример использования (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);
...
}
}
Если у вас нет Java 8, и вы согласны со мной, что включение массивной библиотеки во избежание написания нескольких строк кода - плохая идея:
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();
}
Абонент отвечает за закрытие потока.
// 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;
}
Вы можете использовать API NIO, чтобы сделать это. Я мог бы сделать это с этим кодом до тех пор, пока общий размер файла (в байтах) поместится в 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();
}
}
Я думаю, что это очень быстро, так как использует MappedByteBuffer.
Простой способ сделать это:
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);
Простейший способ чтения байтов из файла
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);
}
}
}
Это один из самых простых способов
String pathFile = "/path/to/file";
byte[] bytes = Files.readAllBytes(Paths.get(pathFile ));
У Guava есть Files.toByteArray(), чтобы предложить вам. У этого есть несколько преимуществ:
- Он охватывает угловой случай, когда файлы сообщают о длине 0, но все еще имеют содержимое
- Он очень оптимизирован, вы получаете исключение OutOfMemoryException, если пытаетесь прочитать большой файл, даже не пытаясь загрузить файл. (Через умное использование file.length())
- Вам не нужно изобретать велосипед.
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);
Используя тот же подход, что и в вики-сообществе, но более чистый и компилируемый из коробки (предпочтительный подход, если вы не хотите импортировать библиотеки Apache Commons, например, на 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();
}
Я считаю, что это самый простой способ:
org.apache.commons.io.FileUtils.readFileToByteArray(file);
ReadFully Считывает байты b.length из этого файла в байтовый массив, начиная с текущего указателя файла. Этот метод читает несколько раз из файла, пока не будет прочитано запрошенное количество байтов. Этот метод блокируется до тех пор, пока не будет прочитано запрошенное количество байтов, не будет обнаружен конец потока или не сгенерировано исключение.
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Если вы хотите прочитать байты в заранее выделенный байтовый буфер, этот ответ может помочь.
Ваше первое предположение, вероятно, будет использовать InputStream read(byte[])
, Однако этот метод имеет недостаток, который делает его неоправданно сложным: нет никакой гарантии, что массив будет действительно полностью заполнен, даже если EOF не обнаружен.
Вместо этого взгляните на DataInputStream readFully(byte[])
, Это оболочка для входных потоков, которая не имеет вышеуказанной проблемы. Кроме того, этот метод выбрасывает при обнаружении EOF. Гораздо приятнее.
Мало того, что следующий способ преобразует файл java.io.File в байт [], я также обнаружил, что это самый быстрый способ чтения в файле при тестировании множества различных методов чтения Java-файлов друг против друга:
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);
}
}
}
//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"
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);
}
}
}
Позвольте мне добавить другое решение без использования сторонних библиотек. Он повторно использует шаблон обработки исключений, который был предложен Scott Stanchfield ( ссылка). И я переместил некрасивую часть в отдельное сообщение (я бы спрятался в каком-то классе 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;
}
1- Традиционный способ
Традиционный способ преобразования заключается в использовании метода Input (Stream ) read() следующим образом:
public static byte[] convertUsingTraditionalWay(File file)
{
byte[] fileBytes = new byte[(int) file.length()];
try(FileInputStream inputStream = new FileInputStream(file))
{
inputStream.read(fileBytes);
}
catch (Exception ex)
{
ex.printStackTrace();
}
return fileBytes;
}
2- Java NIO
В Java 7 вы можете выполнить преобразование с помощью служебного класса Files пакета nio:
public static byte[] convertUsingJavaNIO(File file)
{
byte[] fileBytes = null;
try
{
fileBytes = Files.readAllBytes(file.toPath());
}
catch (Exception ex)
{
ex.printStackTrace();
}
return fileBytes;
}
3- Apache Commons IO
Помимо JDK вы можете выполнить преобразование с помощью библиотеки Apache Commons IO двумя способами:
3.1. IOUtils.toByteArray ()
public static byte[] convertUsingIOUtils(File file)
{
byte[] fileBytes = null;
try(FileInputStream inputStream = new FileInputStream(file))
{
fileBytes = IOUtils.toByteArray(inputStream);
}
catch (Exception ex)
{
ex.printStackTrace();
}
return fileBytes;
}
3.2. FileUtils.readFileToByteArray ()
public static byte[] convertUsingFileUtils(File file)
{
byte[] fileBytes = null;
try
{
fileBytes = FileUtils.readFileToByteArray(file);
}
catch(Exception ex)
{
ex.printStackTrace();
}
return fileBytes;
}
Попробуй это:
try
{
String path="";
InputStream inputStream=new FileInputStream(path);
byte[] data=IOUtils.readFully(inputStream,-1,false);
}
catch (Exception e)
{
}
Не забудьте "импортировать sun.misc.IOUtils";
Другой способ чтения байтов из файла
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();
}
}
Можно сделать так просто (версия Kotlin)
val byteArray = File(path).inputStream().readBytes()
попробуйте это, если у вас целевая версия менее 26 API
private static byte[] readFileToBytes(String filePath) {
File file = new File(filePath);
byte[] bytes = new byte[(int) file.length()];
// funny, if can use Java 7, please uses Files.readAllBytes(path)
try(FileInputStream fis = new FileInputStream(file)){
fis.read(bytes);
return bytes;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
В JDK8
Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();