在Java中将文件转换为byte []

File to byte[] in Java

如何将java.io.File转换为byte[]


从JDK7可以使用Files.readAllBytes(Path)

例子:

1
2
3
4
5
6
import java.io.File;
import java.nio.file.Files;

File file;
// ...(file is initialised)...
byte[] fileContent = Files.readAllBytes(file.toPath());


这取决于什么对你最好。从生产效率角度看,不要重新发明轮子和使用ApacheCommons。它在这里。


1
2
3
4
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/RealAccess Field.HTML


自JDK 7以来-一个衬里:

1
byte[] array = Files.readAllBytes(Paths.get("/path/to/file"));

不需要外部依赖项。


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

最简单的方法类似于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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,从bufferByteArrayOutputStream,从ByteArrayOutputStream到实际生成的数组)。

您还需要确保只在内存中读取一定大小的文件(这通常取决于应用程序):-。

您还需要在该功能之外处理IOException

另一种方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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)。


正如有人所说,ApacheCommons文件实用程序可能具有您要查找的内容。

1
public static byte[] readFileToByteArray(File file) throws IOException

示例使用(Program.java):

1
2
3
4
5
6
7
8
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,我就可以用这段代码来实现这一点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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。


如果你没有Java 8,那么同意我,包括一个大的库来避免写几行代码是一个坏主意:

1
2
3
4
5
6
7
8
9
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();
}

调用方负责关闭流。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// 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;
    }


简单的方法:

1
2
3
4
5
6
7
8
9
10
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);

从文件中读取字节的最简单方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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提供了.tobytearray()文件。它有几个优点:

  • 它涵盖了文件报告长度为0但仍有内容的角情况。
  • 它是高度优化的,如果在加载文件之前尝试读取一个大文件,您会得到一个内存不足的例外。(通过巧妙地使用file.length())
  • 你不必重新发明轮子。

  • 1
    2
    3
    4
    5
    6
    7
    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);


    使用与社区wiki答案相同的方法,但更干净和开箱即用(如果您不想导入ApacheCommons libs,例如在Android上,则首选此方法):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    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();
    }


    我认为这是最简单的方法:

    1
    org.apache.commons.io.FileUtils.readFileToByteArray(file);


    从当前文件指针开始,以可读方式将b.length字节从该文件读取到字节数组中。此方法从文件中重复读取,直到读取请求的字节数。此方法将一直阻塞,直到读取请求的字节数、检测到流结尾或引发异常为止。

    1
    2
    3
    RandomAccessFile f = new RandomAccessFile(fileName,"r");
    byte[] b = new byte[(int)f.length()];
    f.readFully(b);

    如果要将字节读取到预先分配的字节缓冲区中,此答案可能会有所帮助。

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

    相反,看看DataInputStream readFully(byte[])。这是输入流的包装器,没有上述问题。此外,当遇到EOF时,此方法将引发。好多了。


    让我在不使用第三方库的情况下添加另一个解决方案。它重新使用了Scott(link)提出的异常处理模式。我把难看的部分转移到一个单独的消息中(我将隐藏在一些fileutils类中;)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    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;
    }

    10


    从文件中读取字节的另一种方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    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();
            }
        }

    试试这个:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        try
        {
            String path="";

            InputStream inputStream=new FileInputStream(path);

            byte[] data=IOUtils.readFully(inputStream,-1,false);

        }
        catch (Exception e)
        {

        }

    别忘了"导入sun.misc.ioutils;"


    下面的方法不仅将java. i.file转换为字节[],而且当测试许多不同的Java文件读取方法时,我发现它是在文件中读取的最快方法:

    Java.Nio.Field.file

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    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);
        }
      }
    }

    在JDK8中

    1
    2
    3
    4
    Stream<String> lines = Files.lines(path);
    String data = lines.collect(Collectors.joining("
    "
    ));
    lines.close();