在Java中将文件转换为byte
如何将java.io.File
转换为byte[]
?
这取决于最适合你的方式。 生产力明智,不要重新发明轮子并使用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());
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
自JDK 7 – 一个class轮:
byte[] array = Files.readAllBytes(new File("/path/to/file").toPath());
不需要外部依赖。
基本上你必须在内存中阅读它。 打开文件,分配数组,并将文件中的内容读入数组。
最简单的方法是这样的:
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
是一个自定义应用程序exception。 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); ... } }
您也可以使用NIO api来完成它。 只要总文件大小(以字节为单位)适合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非常快。
// 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; }
如果您没有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(); }
呼叫者负责关闭流。
简单的方法:
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); } } }
Guava有Files.toByteArray()为您提供。 它有几个优点:
- 它涵盖了文件报告长度为0但仍有内容的角落情况
- 它是高度优化的,如果在尝试加载文件之前尝试读取大文件,则会出现OutOfMemoryException。 (通过巧妙地使用file.length())
- 你不必重新发明轮子。
使用与社区维基答案相同的方法,但更清晰和开箱即用的编译(如果您不想导入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(); }
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);
我相信这是最简单的方法:
org.apache.commons.io.FileUtils.readFileToByteArray(file);
ReadFully从当前文件指针开始,将此文件中的b.length个字节读入字节数组。 此方法从文件中重复读取,直到读取所请求的字节数。 此方法将一直阻塞,直到读取所请求的字节数,检测到流的末尾或抛出exception。
RandomAccessFile f = new RandomAccessFile(fileName, "r"); byte[] b = new byte[(int)f.length()]; f.readFully(b);
让我在不使用第三方库的情况下添加另一种解决方案。 它重用了Scott ( link )提出的exception处理模式。 我把丑陋的部分移动到一个单独的消息中(我会隐藏在一些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; }
如果要将字节读入预先分配的字节缓冲区,这个答案可能有所帮助。
你的第一个猜测可能是使用InputStream read(byte[])
。 但是,这种方法存在一个缺陷,使其难以使用:即使没有遇到EOF,也无法保证arrays实际上会被完全填满。
相反,看一下DataInputStream readFully(byte[])
。 这是输入流的包装器,没有上述问题。 此外,遇到EOF时抛出此方法。 好多了。
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); } } }
另一种从文件中读取字节的方法
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(); } }
以下方法不仅将java.io.File转换为byte [],我还发现它是一种读取文件的最快方式,当测试许多不同的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); } } }