有没有一种方法可以使用 BufferedReader 读取 ByteBuffer 而不必先将其转换为 String?我想以文本行的形式读取相当大的 ByteBuffer,出于性能原因,我想避免将其写入磁盘。在 ByteBuffer 上调用 toString 不起作用,因为生成的 String 太大(它抛出 java.lang.OutOfMemoryError:Java 堆空间)。我原以为 API 中会有一些东西可以将 ByteBuffer 包装在合适的读取器中,但我似乎找不到合适的东西。
这是一个简短的代码示例,说明了我在做什么):
// input stream is from Process getInputStream()
public String read(InputStream istream)
{
ReadableByteChannel source = Channels.newChannel(istream);
ByteArrayOutputStream ostream = new ByteArrayOutputStream(bufferSize);
WritableByteChannel destination = Channels.newChannel(ostream);
ByteBuffer buffer = ByteBuffer.allocateDirect(writeBufferSize);
while (source.read(buffer) != -1)
{
buffer.flip();
while (buffer.hasRemaining())
{
destination.write(buffer);
}
buffer.clear();
}
// this data can be up to 150 MB.. won't fit in a String.
result = ostream.toString();
source.close();
destination.close();
return result;
}
// after the process is run, we call this method with the String
public void readLines(String text)
{
BufferedReader reader = new BufferedReader(new StringReader(text));
String line;
while ((line = reader.readLine()) != null)
{
// do stuff with line
}
}
最佳答案
不清楚您为什么要使用字节缓冲区作为开始。如果你有一个 InputStream
并且你想为它读取行,为什么不使用 InputStreamReader
包裹在 BufferedReader
?让 NIO 参与进来有什么好处?
在 ByteArrayOutputStream
上调用 toString()
对我来说听起来是个坏主意,即使你有足够的空间:最好将它作为字节数组获取并包装它在一个 ByteArrayInputStream
中,然后是一个 InputStreamReader
,如果你真的必须有一个 ByteArrayOutputStream
。如果您真的想要调用toString()
,至少使用采用字符编码名称的重载 - 否则它将使用系统默认值,即可能不是您想要的。
编辑:好的,所以你真的想使用 NIO。您最终仍在写入 ByteArrayOutputStream
,因此您最终会得到一个包含数据的 BAOS。如果您想避免复制该数据,则需要从 ByteArrayOutputStream
派生,例如:
public class ReadableByteArrayOutputStream extends ByteArrayOutputStream
{
/**
* Converts the data in the current stream into a ByteArrayInputStream.
* The resulting stream wraps the existing byte array directly;
* further writes to this output stream will result in unpredictable
* behavior.
*/
public InputStream toInputStream()
{
return new ByteArrayInputStream(array, 0, count);
}
}
然后您可以创建输入流,将其包装在 InputStreamReader
中,然后将其包装在 BufferedReader
中,然后就可以了。
关于java - 大型 ByteBuffer 的 BufferedReader?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1045632/