Java IO 在文件读取方面优于 Java NIO

Java IO outperforms Java NIO when it comes to file reading

提问人:Ege Hurturk 提问时间:12/29/2020 最后编辑:Ege Hurturk 更新时间:12/30/2020 访问量:383

问:

我相信,在读取文件内容所需的时间方面,新包的性能会优于旧包。但是,根据我的结果,包装似乎优于包装。这是我的测试:nioioionio


import java.io.*;
import java.lang.reflect.Array;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

public class FileTestingOne {

    public static void main(String[] args) {
        long startTime = System.nanoTime();

        File file = new File("hey2.txt");
        try {
            byte[] a = direct(file);
            String s = new String(a);
        }
        catch (IOException err) {
            err.printStackTrace();
        }
        long endTime   = System.nanoTime();
        long totalTime = (endTime - startTime);
        System.out.println(totalTime);
    }

    public static ByteBuffer readFile_NIO(File file) throws IOException {
        RandomAccessFile rFile = new RandomAccessFile(file.getName(), "rw");
        FileChannel inChannel = rFile.getChannel();

        ByteBuffer _buffer = ByteBuffer.allocate(1024);
        int bytesRead = inChannel.read(_buffer);
        while (bytesRead != -1) {
            _buffer.flip();
            while (_buffer.hasRemaining()) {
                byte b = _buffer.get();
            }
            _buffer.clear();
            bytesRead = inChannel.read(_buffer);
        }

        inChannel.close();
        rFile.close();
        return _buffer;
    }

    public static byte[] direct(File file) throws IOException {
        byte[] buffer = Files.readAllBytes(file.toPath());
        return buffer;
    }

    public static byte[] readFile_IO(File file) throws IOException {

        byte[] _buffer = new byte[(int) file.length()];
        InputStream in = null;

        try {
            in = new FileInputStream(file);
            if ( in.read(_buffer) == -1 ) {
                throw new IOException(
                        "EOF reached while reading file. File is probably empty");
            }
        }
        finally {
            try {
                if (in != null)
                    in.close();
            }
            catch (IOException err) {
                // TODO Logging
                err.printStackTrace();
            }
        }
        return _buffer;
    }



}

// Small file
//7566395  -> readFile_NIO
//10790558 -> direct
//707775   -> readFile_IO

// Large file
//9228099  -> readFile_NIO
//737674   -> readFile_IO
//10903324 -> direct

// Very large file
//13700005  -> readFile_NIO
//2837188   -> readFile_IO
//11020507  -> direct

结果是:

  • 小文件:
    • nio实现:7,566,395ns
    • io实现:707,775ns
    • 直接实现:10,790,558ns
  • 大文件:
    • nio实现:9,228,099ns
    • io实现:737,674ns
    • 直接实现:10,903,324ns
  • 非常大的文件:
    • nio实现:13,700,005ns
    • io实现:2,837,188ns
    • 直接实现:11,020,507ns

我想问这个问题,因为(我相信)包是非阻塞的,因此它需要更快,对吧?nio

谢谢

编辑:

将 ms 更改为 ns

Java 时间 IO NIO

评论

1赞 Reto Höhener 12/29/2020
此外,请尝试使用更大的缓冲区(至少 1 MB)。这是纳秒 (ns)。还要比较 ,而不是使用 。并做一些有意义的工作,比如将内容读成 String。new FileInputStream(file).getChannel()RandomAccessFile
0赞 rmunge 12/30/2020
在测量每个方法的时间之前,是否清除了文件系统缓存?否则,您的测量结果将不具有可比性。

答:

1赞 divisionby0 12/29/2020 #1

内存映射文件(或 )是 Java NIO 的一部分,有助于提高性能。MappedByteBuffer

Java NIO 中的非阻塞意味着线程不必等待下一个数据读取。它不一定会影响完整操作(如读取处理文件)的性能。

评论

0赞 Ege Hurturk 12/30/2020
我理解。谢谢!