【问题标题】:Is there a reason to use BufferedReader over InputStreamReader when reading all characters?读取所有字符时是否有理由使用 BufferedReader 而不是 InputStreamReader?
【发布时间】:2010-09-07 01:54:06
【问题描述】:

我目前使用下面的函数来做一个简单的HTTP GET。

public static String download(String url) throws java.io.IOException {
    java.io.InputStream s = null;
    java.io.InputStreamReader r = null;
    //java.io.BufferedReader b = null;
    StringBuilder content = new StringBuilder();
    try {
        s = (java.io.InputStream)new URL(url).getContent();

        r = new java.io.InputStreamReader(s);
        //b = new java.io.BufferedReader(r);

        char[] buffer = new char[4*1024];
        int n = 0;
        while (n >= 0) {
            n = r.read(buffer, 0, buffer.length);
            if (n > 0) {
                content.append(buffer, 0, n);
            }
        }
    }
    finally {
        //if (b != null) b.close();
        if (r != null) r.close();
        if (s != null) s.close();
    }
    return content.toString();
}

我认为没有理由使用BufferedReader,因为我只是要按顺序下载所有内容。我是否认为在这种情况下BufferedReader 没有用处?

【问题讨论】:

    标签: java performance http io buffer


    【解决方案1】:

    在这种情况下,我会按照您的做法(使用字节数组进行缓冲,而不是使用流缓冲区之一)。

    但也有例外。您可以在 servlet API 中看到缓冲区(这次是输出)。在调用 flush() 之前,数据不会写入底层流,允许您缓冲输出,然后在发生错误时转储缓冲区并改为写入错误页面。如果您需要使用 mark(int)reset() 重置流以重新读取,则可以缓冲输入。例如,您可能会在决定将流传递给哪个内容处理程序之前检查文件头。

    无关,但我认为你应该重写你的流处理。这种模式最适合避免资源泄漏:

        InputStream stream = new FileInputStream("in");
        try { //no operations between open stream and try block
            //work
        } finally { //do nothing but close this one stream in the finally
            stream.close();
        }
    

    如果您要打开多个流,请嵌套 try/finally 块。

    您的代码正在做的另一件事是假设返回的内容以 VM 的默认字符集进行编码(尽管这可能就足够了,具体取决于用例)。

    【讨论】:

      【解决方案2】:

      您是对的,如果您使用 BufferedReader 读取 HTTP 内容和标头,您将需要 InputStreamReader,以便您可以逐字节读取。

      BufferedReader 在这种情况下有时会做一些奇怪的事情...尤其是在读取 HTTP POST 标头时,有时您将无法读取 POST 数据,如果您使用 InputStreamReader 您可以读取内容长度并读取那么多字节...

      【讨论】:

        【解决方案3】:

        InputStreamReader 的 read() 方法之一的每次调用都可能导致从底层字节输入流中读取一个或多个字节。为了实现字节到字符的高效转换,可能会从底层流中预先读取比满足当前读取操作所需的更多的字节。

        【讨论】:

          【解决方案4】:

          我的直觉告诉我,由于您已经使用字节数组执行缓冲,因此使用 BufferedReader 是多余的。

          【讨论】:

            猜你喜欢
            • 2018-06-16
            • 2017-11-10
            • 2019-10-17
            • 2017-02-14
            • 1970-01-01
            • 1970-01-01
            • 2015-05-12
            • 2010-12-31
            • 2021-12-01
            相关资源
            最近更新 更多