Java中的文件到字节[]
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/858980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
File to byte[] in Java
提问by Ben Noland
How do I convert a java.io.File
to a byte[]
?
如何将 a 转换java.io.File
为 a byte[]
?
采纳答案by svachon
It depends on what best means for you. Productivity wise, don't reinvent the wheel and use Apache Commons. Which is here IOUtils.toByteArray(InputStream input)
.
这取决于什么对你来说是最好的。生产力明智,不要重新发明轮子并使用 Apache Commons。这是在这里IOUtils.toByteArray(InputStream input)
。
回答by Cuga
// 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;
}
回答by Amit
You can use the NIO api as well to do it. I could do this with this code as long as the total file size (in bytes) would fit in an int.
你也可以使用 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();
}
}
I think its very fast since its using MappedByteBuffer.
我认为它非常快,因为它使用了 MappedByteBuffer。
回答by Tom
As someone said, Apache Commons File Utilsmight have what you are looking for
正如有人所说,Apache Commons File Utils可能有你想要的
public static byte[] readFileToByteArray(File file) throws IOException
Example use (Program.java
):
示例使用 ( 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);
...
}
}
回答by Mihai Toader
Basically you have to read it in memory. Open the file, allocate the array, and read the contents from the file into the array.
基本上你必须在内存中读取它。打开文件,分配数组,将文件中的内容读入数组。
The simplest way is something similar to this:
最简单的方法与此类似:
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();
}
This has some unnecessary copying of the file content (actually the data is copied three times: from file to buffer
, from buffer
to ByteArrayOutputStream
, from ByteArrayOutputStream
to the actual resulting array).
这有一些不必要的文件内容复制(实际上数据被复制了三次:从文件到buffer
,从buffer
到ByteArrayOutputStream
,从ByteArrayOutputStream
到实际结果数组)。
You also need to make sure you read in memory only files up to a certain size (this is usually application dependent) :-).
您还需要确保在内存中只读取特定大小的文件(这通常取决于应用程序):-)。
You also need to treat the IOException
outside the function.
您还需要处理IOException
函数的外部。
Another way is this:
另一种方法是这样的:
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;
}
This has no unnecessary copying.
这没有不必要的复制。
FileTooBigException
is a custom application exception.
The MAX_FILE_SIZE
constant is an application parameters.
FileTooBigException
是自定义应用程序异常。该MAX_FILE_SIZE
常数是一个应用程序的参数。
For big files you should probably think a stream processing algorithm or use memory mapping (see java.nio
).
对于大文件,您可能应该考虑使用流处理算法或使用内存映射(请参阅 参考资料java.nio
)。
回答by Andreas Dolk
Let me add another solution without using third-party libraries. It re-uses an exception handling pattern that was proposed by Scott(link). And I moved the ugly part into a separate message (I would hide in some FileUtils class ;) )
让我在不使用第三方库的情况下添加另一个解决方案。它重用了Scott提出的异常处理模式(链接)。我将丑陋的部分移到单独的消息中(我会隐藏在某些 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;
}
回答by Alan
From JDK 7you can use Files.readAllBytes(Path)
.
从JDK 7 开始,您可以使用Files.readAllBytes(Path)
.
Example:
例子:
import java.io.File;
import java.nio.file.Files;
File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());
回答by Dmitry Mitskevich
import java.io.RandomAccessFile;
RandomAccessFile f = new RandomAccessFile(fileName, "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
Documentation for Java 8: http://docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html
Java 8 文档:http: //docs.oracle.com/javase/8/docs/api/java/io/RandomAccessFile.html
回答by manmal
Using the same approach as the community wiki answer, but cleaner and compiling out of the box (preferred approach if you don't want to import Apache Commons libs, e.g. on Android):
使用与社区 wiki 答案相同的方法,但更干净并且开箱即用(如果您不想导入 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();
}
回答by Laurens Holst
If you want to read bytes into a pre-allocated byte buffer, this answer may help.
如果您想将字节读入预先分配的字节缓冲区,此答案可能会有所帮助。
Your first guess would probably be to use InputStream read(byte[])
. However, this method has a flaw that makes it unreasonably hard to use: there is no guarantee that the array will actually be completely filled, even if no EOF is encountered.
您的第一个猜测可能是使用InputStream read(byte[])
. 但是,这种方法有一个缺陷,使其难以使用:即使没有遇到 EOF,也不能保证数组实际上会被完全填满。
Instead, take a look at DataInputStream readFully(byte[])
. This is a wrapper for input streams, and does not have the above mentioned issue. Additionally, this method throws when EOF is encountered. Much nicer.
相反,看看DataInputStream readFully(byte[])
. 这是输入流的包装器,没有上述问题。此外,此方法在遇到 EOF 时抛出。好多了。