¿Cómo convierto java.io.File
a a byte[]
?
¿Cómo convierto java.io.File
a a byte[]
?
Respuestas:
Depende de lo que sea mejor para ti. En cuanto a la productividad, no reinvente la rueda y use Apache Commons. Que esta aqui IOUtils.toByteArray(InputStream input)
.
File
to byte[]
? Estoy usando Java6, así que no puedo usar los métodos NIO :(
Desde JDK 7 puedes usar Files.readAllBytes(Path)
.
Ejemplo:
import java.io.File;
import java.nio.file.Files;
File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());
Desde JDK 7 - un revestimiento:
byte[] array = Files.readAllBytes(Paths.get("/path/to/file"));
No se necesitan dependencias externas.
import java.nio.file.Files;
y import java.nio.file.Paths;
si aún no lo ha hecho.
import java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Documentación para Java 8: http://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html
Básicamente hay que leerlo en la memoria. Abra el archivo, asigne la matriz y lea el contenido del archivo en la matriz.
La forma más simple es algo similar a esto:
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();
}
Esto tiene una copia innecesaria del contenido del archivo (en realidad, los datos se copian tres veces: de archivo a buffer
, de buffer
a ByteArrayOutputStream
, de ByteArrayOutputStream
a la matriz resultante real).
También debe asegurarse de leer en la memoria solo archivos de un cierto tamaño (esto generalmente depende de la aplicación) :-).
También debe tratar el IOException
exterior de la función.
Otra forma es esta:
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;
}
Esto no tiene copia innecesaria.
FileTooBigException
es una excepción de aplicación personalizada. La MAX_FILE_SIZE
constante es una aplicación de parámetros.
Para archivos grandes, probablemente deberías pensar en un algoritmo de procesamiento de flujo o usar mapeo de memoria (ver java.nio
).
Como alguien dijo, Apache Commons File Utils podría tener lo que estás buscando
public static byte[] readFileToByteArray(File file) throws IOException
Ejemplo de uso ( 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);
...
}
}
También puede usar la API de NIO para hacerlo. Podría hacer esto con este código siempre que el tamaño total del archivo (en bytes) se ajuste a 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();
}
}
Creo que es muy rápido ya que está usando MappedByteBuffer.
Si no tiene Java 8, y está de acuerdo conmigo en que incluir una biblioteca masiva para evitar escribir algunas líneas de código es una mala idea:
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();
}
La persona que llama es responsable de cerrar la transmisión.
// 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!");
¿Qué debemos hacer cuando el archivo es demasiado grande? ¿Hay también algún ejemplo al respecto?
Manera simple de hacerlo:
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);
La forma más simple de leer bytes del archivo
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);
}
}
}
.*
, se considera una mala práctica.
Guava tiene Files.toByteArray () para ofrecerte. Tiene varias ventajas:
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);
Usando el mismo enfoque que la respuesta wiki de la comunidad, pero más limpio y compilado de fábrica (enfoque preferido si no desea importar las bibliotecas de Apache Commons, por ejemplo, en 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();
}
Creo que esta es la forma más fácil:
org.apache.commons.io.FileUtils.readFileToByteArray(file);
ReadFully Lee b.length bytes de este archivo en la matriz de bytes, comenzando en el puntero del archivo actual. Este método lee repetidamente del archivo hasta que se lee el número de bytes solicitado. Este método bloquea hasta que se lee el número de bytes solicitado, se detecta el final de la secuencia o se produce una excepción.
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Si desea leer bytes en un búfer de bytes preasignado, esta respuesta puede ayudar.
Su primera suposición probablemente sería usar InputStream read(byte[])
. Sin embargo, este método tiene una falla que lo hace irrazonablemente difícil de usar: no hay garantía de que la matriz se llene completamente, incluso si no se encuentra EOF.
En cambio, échale un vistazo DataInputStream readFully(byte[])
. Este es un contenedor para flujos de entrada y no tiene el problema mencionado anteriormente. Además, este método se produce cuando se encuentra EOF. Mucho más bonito.
La siguiente manera no solo convierte un archivo java.io.File a un byte [], también descubrí que es la forma más rápida de leer un archivo, al probar muchos métodos diferentes de lectura de archivos Java entre sí:
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);
}
}
}
Permítanme agregar otra solución sin usar bibliotecas de terceros. Reutiliza un patrón de manejo de excepciones propuesto por Scott ( enlace ). Y moví la parte fea a un mensaje separado (me escondería en alguna clase de 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);
}
}
}
Otra forma de leer bytes del archivo
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"
Prueba esto :
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);
}
En JDK8
Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();