【问题标题】:Best way to read an input stream to a buffer将输入流读取到缓冲区的最佳方法
【发布时间】:2013-01-18 05:32:55
【问题描述】:

将任何输入流读取到缓冲区有两种方法。有人可以帮助我了解哪种方法更好,为什么?以及在什么情况下我们应该使用每种方法?

  • 逐行读取并将其附加到缓冲区。

例如:

public String fileToBuffer(InputStream is, StringBuffer strBuffer) throws IOException{
    StringBuffer buffer = strBuffer;
    InputStreamReader isr = null;

    try {
        isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);
        String line = null;

        while ((line = br.readLine()) != null) {
            buffer.append(line + "\n");
        }
    } finally {
        if (is != null) {
            is.close();
        }
        if (isr != null) {
            isr.close();
        }
    }

    return buffer.toString();
}

  • 读取缓冲区大小,即 char 数组中的 1024 个字节。

例如:

InputStreamReader isr = new InputStreamReader(is);
final int bufferSize = 1024;
char[] buffer = new char[bufferSize];
StringBuffer strBuffer = new StringBuffer();

/* read the base script into string buffer */
try {
    while (true) {
        int read = isr.read(buffer, 0, bufferSize);
        if (read == -1) {
           break;
        }

        strBuffer.append(buffer, 0, read);
     }
} catch (IOException e) {
}

【问题讨论】:

    标签: java file-io io


    【解决方案1】:

    考虑

    public String fileToBuffer(InputStream is, StringBuffer strBuffer) throws IOException {
        StringBuilder sb = new StringBuilder(strBuffer);
        try (BufferedReader rdr = new BufferedReader(new InputStreamReader(is))) { 
            for (int c; (c = rdr.read()) != -1;) {
                sb.append((char) c);
    
            }
        }
        return sb.toString();
    }
    

    【讨论】:

    • 您提供单字节缓冲区版本作为改进
    【解决方案2】:

    取决于目的。

    使用文本文件读取行(如果需要)。

    对于原始二进制数据,请使用字节块。

    在您的示例中,字节块更健壮。 如果一行太长,打断了一些中间对象怎么办?

    如果你的文件是二进制文件,你知道一行有多大吗? 可能是文件的大小。

    试图“吞下”太大的字符串可能会导致 ErrorOutOfMemory。 对于 1024 字节,它(好的 - 几乎)永远不会发生。

    按 1024 字节分块可能需要更长的时间,但更可靠。

    【讨论】:

    • 他的示例中没有字节块。他有大块的字符。
    • 谢谢,但变化不大。逻辑还是一样的。
    【解决方案3】:

    使用 'readLine' 并不那么整洁。提问者的方法 2 是相当标准的,但下面的方法是独特的(并且可能更好):

    //read the whole inputstream and put into a string
    public String inputstream2str(InputStream stream) {
      Scanner s = new Scanner(stream).useDelimiter("\\A");
      return s.hasNext()? s.next():"";
    }
    

    您可以从字符串转换为字节数组或任何您想要的缓冲区。

    【讨论】:

    • 为什么逐行阅读很危险? (不是我不同意,但你应该说明你的理由。)鉴于此,逐行阅读和使用换行符分隔符扫描有什么区别?答案:零。那为什么要推荐呢?
    • 逐行读取可能很危险,因为如果开始逐行读取二进制文件,则行的大小可能等于文件的大小。仅在处理文本文件时,行才有意义。
    猜你喜欢
    • 1970-01-01
    • 2010-12-05
    • 2015-01-09
    • 2011-07-01
    • 2012-12-25
    • 2015-03-19
    • 2016-12-25
    • 1970-01-01
    • 2018-12-24
    相关资源
    最近更新 更多