我如何将java.io.File转换为字节[]?


当前回答

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);

其他回答

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);
        }
    }
}

正如有人所说,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);
        ...
    }
}

基本上你必须在记忆中读它。打开文件,分配数组,并将文件中的内容读入数组。

最简单的方法是这样的:

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();
}

这对文件内容有一些不必要的复制(实际上数据复制了三次:从文件到缓冲区,从缓冲区到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)。

在JDK8

Stream<String> lines = Files.lines(path);
String data = lines.collect(Collectors.joining("\n"));
lines.close();

如果您想将字节读入预分配的字节缓冲区,这个答案可能会有所帮助。

您的第一个猜测可能是使用InputStream read(byte[])。然而,这种方法有一个缺陷,使得它难以使用:即使没有遇到EOF,也不能保证数组实际上会被完全填充。

相反,看一下DataInputStream readFully(byte[])。这是一个输入流的包装器,没有上面提到的问题。此外,该方法在遇到EOF时抛出。好得多。