Rob*_*Rob 3 java nio bytebuffer bufferedreader
有没有办法用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
}
}
Run Code Online (Sandbox Code Playgroud)
目前尚不清楚为什么要使用字节缓冲区来开始.如果你有一个InputStream并且你想读它的线,你为什么不用一个InputStreamReader包装BufferedReader?让NIO参与的好处是什么?
调用toString()上ByteArrayOutputStream像一个坏主意的声音对我来说,即使你必须为它的空间:更好地得到它作为一个字节数组,敷在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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后你可以创建输入流,将其包装成一个InputStreamReader包装BufferedReader,然后你就可以了.
| 归档时间: |
|
| 查看次数: |
22435 次 |
| 最近记录: |