Java -- 从文件中读取。输入流与读取器

2022-09-04 03:04:56

在我看到的每个从文件中读取的Java实现中,我几乎总是看到一个用于逐行读取的文件读取器。我的想法是,这将是非常低效的,因为它需要每行一个系统调用。

相反,我一直在做的是使用输入流并直接获取字节。在我的实验中,这明显更快。我的测试是一个1MB的文件。

    //Stream method
    try {
        Long startTime = new Date().getTime();

        InputStream is = new FileInputStream("test");
        byte[] b = new byte[is.available()];
        is.read(b);
        String text = new String(b);
        //System.out.println(text);

        Long endTime = new Date().getTime();
        System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime));

    }
    catch (Exception e) {
        e.printStackTrace();
    }

    //Reader method
    try {
        Long startTime = new Date().getTime();

        BufferedReader br = new BufferedReader(new FileReader("test"));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
            sb.append("\n");
        }
        String text = sb.toString();

        Long endTime = new Date().getTime();
        System.out.println("Text length: " + text.length() + ", Total time: " + (endTime - startTime));

    }
    catch (Exception e) {
        e.printStackTrace();
    }

这给出了以下结果:

Text length: 1054631, Total time: 9
Text length: 1034099, Total time: 22

那么,为什么人们使用阅读器而不是流呢?

如果我有一个方法,它采用文本文件并返回包含所有文本的字符串,那么使用流进行操作是否一定更好?


答案 1

你正在比较苹果和香蕉。即使使用缓冲读取器,一次读取一行的效率也会低于尽可能快地获取数据。请注意,不鼓励使用可用的,因为它并非在所有情况下都是准确的。当我开始使用密码流时,我自己发现了这一点。


答案 2

FileReader通常与 结合使用,因为通常逐行读取文件是有意义的,特别是如果文件具有明确定义的记录结构,其中每条记录对应于一行。BufferedReader

此外,可以简化处理字符编码和转换的一些工作,如javadocs中所述:FileReader

用于读取字符文件的便利类。此类的构造函数假定默认字符编码和默认字节缓冲区大小是合适的...FileReader 用于读取字符流。