37

让我谨慎地开始这篇文章。当谈到 Java 时,我是一个完全的初学者。我一直在断断续续地编写 PHP,但我已经准备好做一个桌面应用程序,所以出于各种原因我决定使用 Java。

我正在处理的应用程序处于初始阶段(少于 5 个类),我需要从本地文件中读取字节。通常,这些文件当前小于 512kB(但将来可能会变得更大)。目前,我正在使用 aFileInputStream将文件读入三字节数组,完全满足我的要求。但是,我看到了 a BufferedInputStream,并且想知道我目前这样做的方式是否最好,或者我是否也应该使用 a BufferedInputStream

我已经做了一些研究,并在 Stack Overflow 上阅读了一些问题,但我仍然无法理解何时使用和不使用BufferedInputStream. 在我的情况下,我读取字节的第一个数组只有几个字节(小于 20)。如果我收到的数据在这些字节中是好的,那么我将文件的其余部分读入另外两个不同大小的字节数组。

我还听到很多人提到分析,以查看在每种特定情况下哪个更有效,但是,我没有分析经验,我不确定从哪里开始。我也想对此提出一些建议。

很抱歉写了这么长的帖子,但我真的很想学习和理解做这些事情的最佳方法。我总是有第二次猜测我的决定的坏习惯,所以我希望得到一些反馈。谢谢!

4

5 回答 5

84

如果你一直在做小读取,那么 aBufferedInputStream会给你带来更好的性能。无缓冲流上的每个读取请求通常会导致对操作系统的系统调用以读取请求的字节数。进行系统调用的开销可能是每个系统调用数千条机器指令。缓冲流通过对内部缓冲区进行一次大读取(例如)最多 8k 字节,然后从该缓冲区分发字节来减少这种情况。这可以大大减少系统调用的数量。

但是,如果您一直在进行大量读取(例如 8k 或更多),那么 aBufferedInputStream会减慢速度。您通常不会减少系统调用的数量,并且缓冲引入了额外的数据复制步骤。

在您的用例中(您首先读取 20 字节的块,然后读取大量大块)我会说使用 aBufferedInputStream更有可能降低性能而不是提高性能。但最终,这取决于实际的读取模式。

于 2010-06-26T02:57:40.310 回答
5

如果您使用相对较大的数组一次读取一个块的数据,那么BufferedInputStream只会引入一个浪费的副本。(请记住,read不一定要读取所有数组 - 您可能想要DataInputStream.readFully)。在进行BufferedInputStream大量小读取时获胜。

于 2010-06-26T02:24:34.463 回答
1

BufferedInputStream 会提前读取更多您需要的文件。据我了解,它提前做了更多的工作,比如 1 个大的连续磁盘读取,而不是在一个紧密的循环中做很多。

至于分析 - 我喜欢 netbeans 内置的分析器。这真的很容易上手。:-)

于 2010-06-26T02:20:47.503 回答
1

我无法谈论分析,但根据我开发 Java 应用程序的经验,我发现使用任何缓冲区类——BufferedInputStream、StringBuffer——我的应用程序都异常快。因此,我什至将它们用于最小的文件或字符串操作。

于 2010-06-26T02:21:09.730 回答
-2
    import java.io.*;
    class BufferedInputStream
    {
            public static void main(String arg[])throws IOException
            {
                FileInputStream fin=new FileInputStream("abc.txt");
                BufferedInputStream bis=new BufferedInputStream(fin);
                int size=bis.available();
                while(true)
                {
                        int x=bis.read(fin);
                        if(x==-1)
                        {
                                bis.mark(size);
                                System.out.println((char)x);
                        }
                }
                        bis.reset();
                        while(true)
                        {
                                int x=bis.read();
                                if(x==-1)
                                {
                                    break;
                                    System.out.println((char)x);
                                }
                        }

            }

    }
于 2013-06-26T06:26:20.703 回答