在Java中读取相对较大的字节文件的最快方法

2022-09-02 23:05:35

使用Java的I / O方法读取相对较大的文件的最快方法是什么?我当前的解决方案使用保存到一个字节数组,其中分配了1024个字节。每个缓冲区都保存在 中供以后使用。整个过程通过单独的线程(可调用接口)调用。BufferedInputStreamArrayList

虽然不是很快。

    ArrayList<byte[]> outputArr = new ArrayList<byte[]>();      
    try {
        BufferedInputStream reader = new BufferedInputStream(new FileInputStream (dir+filename));

        byte[] buffer = new byte[LIMIT]; // == 1024 
            int i = 0;
            while (reader.available() != 0) {
                reader.read(buffer);
                i++;
                if (i <= LIMIT){
                    outputArr.add(buffer);
                    i = 0;
                    buffer = null;
                    buffer = new byte[LIMIT];
                }
                else continue;              
            }

         System.out.println("FileReader-Elements: "+outputArr.size()+" w. "+buffer.length+" byte each.");   

答案 1

我会使用一个内存映射文件,它足够快,可以在同一线程中完成。

final FileChannel channel = new FileInputStream(fileName).getChannel();
MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());

// when finished
channel.close();

这假设文件小于 2 GB,并且需要 10 毫秒或更短的时间。


答案 2

不要使用:它不可靠。不要忽略该方法的结果:它告诉您实际读取了多少字节。如果你想读取内存中的所有内容,请使用 ByteArrayOutputStream 而不是使用 :available()read()List<byte[]>

ByteArrayOutputStream baos = new ByteArrayOutputStream();
int read;
while ((read = reader.read(buffer)) >= 0) {
    baos.write(buffer, 0, read);
}
byte[] everything = baos.toByteArray();

我认为 1024 作为缓冲区大小有点小。我会使用更大的缓冲区(如16 KB或32KB)

请注意,Apache commons IO和Guava具有为您执行此操作的实用程序方法,并且已经进行了优化。


推荐