Java BufferedInputStream的使用

Java BufferedInputStream的使用,java,fileinputstream,bufferedinputstream,Java,Fileinputstream,Bufferedinputstream,让我在这篇文章的序言中谨慎一点。说到Java,我完全是个初学者。我已经断断续续地编写PHP有一段时间了,但我已经准备好制作一个桌面应用程序,所以出于各种原因,我决定使用Java 我正在处理的应用程序正处于开始阶段(少于5个类),我需要从本地文件读取字节。通常,文件当前小于512kB(但将来可能会变大)。目前,我正在使用FileInputStream将文件读入三字节数组,这完全满足了我的要求。但是,我看到前面提到了一个BufferedInputStream,我想知道我目前这样做的方式是否最好,或者

让我在这篇文章的序言中谨慎一点。说到Java,我完全是个初学者。我已经断断续续地编写PHP有一段时间了,但我已经准备好制作一个桌面应用程序,所以出于各种原因,我决定使用Java

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

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

我还听到很多人提到评测,以了解在每个特定情况下哪个更有效,但是,我没有评测经验,也不确定从哪里开始。我也希望得到一些建议


我很抱歉这么长的帖子,但我真的很想学习和理解做这些事情的最佳方式。我总是有一个坏习惯,即事后诸葛亮,所以我希望得到一些反馈。谢谢

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


至于评测——我喜欢内置在netbeans中的评测器。这很容易开始。:-)

我不能谈论评测,但从我开发Java应用程序的经验来看,我发现使用任何缓冲区类——BufferedInputStream、StringBuffer——我的应用程序速度都非常快。因此,即使是最小的文件或字符串操作,我也会使用它们。

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

如果您一直在进行小读取,则
BufferedInputStream
将为您提供显著更好的性能。非缓冲流上的每个读取请求通常会导致系统调用操作系统来读取请求的字节数。执行系统调用的开销可能是每个系统调用数千条机器指令。缓冲流通过对内部缓冲区进行一次最大8k字节的大读取,然后从该缓冲区分发字节来减少这种情况。这可以大大减少系统调用的数量

但是,如果您一直在进行大量读取(例如8k或更多),则
BufferedInputStream
会稍微降低速度。通常不会减少系统调用的数量,而缓冲会引入额外的数据复制步骤


在您的用例中(首先读取一个20字节的块,然后读取大量的大块),我认为使用
BufferedInputStream
更有可能降低性能而不是提高性能。但归根结底,这取决于实际的阅读模式。

谢谢你的建议。我听到有人提到NetBeans中的profilier。我开始使用NetBeans,但是,我现在只使用纯文本编辑器。我觉得通过这种方式我学到了更多关于语言的知识。你还有什么其他建议吗?文本编辑器很棒,但如果你给客户开账单的话,这有点像踩着自卸卡车。如果希望避免在ide中进行评测,可以尝试hprof:谢谢@jskaggz。我会去hprof看看。顺便说一句,我是为自己制作这个应用程序的,所以我并不是真的在制定时间表,但我同意,如果是为客户机开发的,我肯定会使用ide来加速它。当你使用BufferedInputStream时,你通常是为它指定一个特定大小的块来缓冲,还是让它自动决定?这取决于你。正如Stephen C在上面所说的,如果这个数字与系统调用中使用的数据页大小(比如4k)不一致,那么您只需通过创建瓶颈来打击自己。把它想象成用铲子填满沙袋。如果你往铲子里舀太多或太少的沙子,你只会降低效率/性能。我是一个优秀代码的倡导者。但是,如果您刚刚开始,那么让它工作并在以后进行优化并没有什么错。这些东西可能是兔子洞。@jasonmccury何时使用
read()
逐字节,何时使用
read(byte[])
字节数组。因为我认为读取数组总是更好的。然后你能给我举个例子,在哪里使用
read()
byte by byte或
read(byte[])
字节数组。或者
BufferedInputStream
?我想我明白你的意思。我再问你一个问题。我看到FileInputStream的构造函数以字节[]作为参数。目前,我正在使用for循环来读取所需的字节,但是,我假设使用此参数会更有效?我还假设使用for循环不断地从FileInputStream调用read就是您所说的大量小读取?我很抱歉听起来如此粗鲁,但出于某种原因,我很难完全理解这一点。谢谢你的回答@莫萨尤米大师
    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);
                                }
                        }

            }

    }