读取所有字符时是不是有理由使用 BufferedReader 而不是 InputStreamReader?

Posted

技术标签:

【中文标题】读取所有字符时是不是有理由使用 BufferedReader 而不是 InputStreamReader?【英文标题】: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 没有用处?

【问题讨论】:

【参考方案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 是多余的。

【讨论】:

以上是关于读取所有字符时是不是有理由使用 BufferedReader 而不是 InputStreamReader?的主要内容,如果未能解决你的问题,请参考以下文章

将所有环境迁移到最新版本后,是不是有理由保留 EF 迁移代码?

系统学习 Java IO (十四)----字符读写缓存和回退 BufferedReader/BufferedWriter & PushbackReader

在 Java 9 中是不是有充分的理由使用带有新接口的抽象类? [复制]

javamail 阅读邮件时,有啥理由使用 Message 而不是 MimeMessage 等?

如何读取文件的编码信息 c语言

从标准输入读取所有文本到字符串