2

下面的代码似乎只写了StringBuilder中文件的一小部分——为什么?

    Reader rdr = new BufferedReader(new InputStreamReader(new FileInputStream(...)));
    StringBuilder buf = new StringBuilder();
    CharBuffer cbuff = CharBuffer.allocate(1024);
    while(rdr.read(cbuff) != -1){
        buf.append(cbuff);
        cbuff.clear();
    }
    rdr.close();

更多信息:该文件比 CharBuffer 大,我也可以从调试器中看到 charbuffer 确实按预期填充。唯一进入 StringBuilder 的部分似乎来自文件中间的某个地方。我正在使用openJDK7。我想知道为什么它会表现出这样的行为以及如何解决这个问题。

4

2 回答 2

7

正如 Peter Lawrey 所说,您需要cbuff.flip()在读写之间调用。似乎 append 将从缓冲区的位置读取,如果我们不调用cbuff.flip(). 仍然写入中间某处的一部分的原因是,最终缓冲区不会被完全填满,因此一些“旧”字节仍将位于缓冲区中的位置和缓冲区的末尾之间。

谜团已揭开 :-)

于 2012-10-31T09:49:12.770 回答
1

自 1.0 以来,所有这些类都已成为 JDK 的一部分。我怀疑其中任何一个都需要修复。

对于通常的习惯用法,您的代码还有很长的路要走。这是为了作为一种学习练习,一个出了差错?还是您真的想将其放入应用程序中?

以下是我希望看到使用这些类的方式:

public static final String NEWLINE = System.getProperty("line.separator");

public String readContents(File f) throws IOException {
    StringBuilder builder = new StringBuilder(1024);
    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader(f));
        String line;
        while ((line = br.readLine()) != null) {
            builder.append(line).append(NEWLINE);
        }
    } finally { 
        closeQuietly(br);
    }
    return builder.toString();
}
于 2012-10-31T09:17:22.360 回答