有没有一种方法可以使用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有什么好处?
调用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);
}
}
然后,您可以创建输入流,将其包装为,将其InputStreamReader
包装为BufferedReader
,然后就可以离开了。
问题内容: 根据文档,使用默认缓冲区大小,而第二个构造函数允许设置缓冲区大小。 public BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。 但是,文档没有提到默认的缓冲区大小是多少。 BufferedReader的默认缓冲区大小是多少? 问题答案: 默认缓冲区大小为8192个字符 http://developer.android.com/ref
根据文档,使用默认缓冲区大小,而第二个构造函数,允许设置缓冲区大小。 公共缓冲区读取器(读取器输入) 创建使用默认大小的输入缓冲区的缓冲字符输入流。 但是,文档没有提到默认缓冲区大小。 BufferedReader的默认缓冲区大小是多少?
问题内容: 构造函数中的缓冲区大小是什么意思? 当我编写程序时: 输出: 然后,缓冲区大小是什么意思,正如我希望的那样,它只能读取两个字符。但事实并非如此。 问题答案: 顾名思义,缓冲输入。这意味着它会在将输入源传递给您之前从输入源读取到缓冲区。此处的缓冲区大小是指其缓冲的字节数。 从大多数来源读取输入非常慢。仅2个字节的缓冲区将损害性能,因为您的程序很可能大部分时间都在等待输入。缓冲区大小为2时
问题内容: 我正在使用类在缓冲区中逐行读取。当读取缓冲区的最后一行时,我想再次从缓冲区的开头开始读取。我已经阅读过有关和的信息,我不确定它的用法,但我认为它们不能帮助我。 有人知道到达最后一行后如何从缓冲区的开头开始读取吗?像我们可以使用的? 问题答案: 标记/重置是您想要的,但是您不能真正在BufferedReader上使用它,因为它只能重置一定数量的字节(缓冲区大小)。如果您的文件大于该文件,
我已经在网上搜索了几天这种现象,我可以找到一个类似问题的片段,这表明可能与底层的InputStreamReader和/或StreamDecoder有关,但这开始超出了我的专业知识。(见本链接) 所以我的问题是,我是否正确地实现了BufferedReader,以及如何解决我所看到的问题,以便在没有不必要的延迟的情况下获得每一行。
我目前正在处理一些小的endian二进制数据,我已经到了一个尴尬的地步,需要将奇数字节转换成整数值。 现在使用类,我能够很好地使用函数读取int和long,它们分别读取4和8个字节。 然而,在本例中,我需要读取三个字节,并将它们转换为int。我尝试过使用(2字节1字节),但我认为这不是正确的方法。 我猜我需要对字节进行位移位才能得到正确的int值,但我总是对位移位感到困惑。 此外,我还以为字节缓冲