Java中的内存流
Posted
技术标签:
【中文标题】Java中的内存流【英文标题】:Memory Stream in Java 【发布时间】:2012-01-16 05:25:17 【问题描述】:我正在寻找 Java 中的内存流实现。实施 应该大致仿照.NET memory stream实现。
基本上我想有一个必须工厂的课程MemoryStream
方法:
class MemoryStream
MemoryInput createInput();
MemoryOutput createOutput();
class MemoryInput extends InputStream
long position();
void seek(long pos);
class MemoryOutput extends OutputStream
long position();
void seek(long pos);
所以一旦我有一个来自 MemoryStream
类的实例,我
应该能够同时创建
输入和输出流,这也应该允许
任何方向的定位。内存流需要
不是圆形的,它应该适用于小尺寸
并自动成长。内存流只需要
被限制在一个进程中。
是否有可用的开箱即用代码?
【问题讨论】:
【参考方案1】:ByteArrayInputStream
和 ByteArrayOutputStream
是您要查找的内容。
这些是接口InputStream
和OutputStream
的实现,它们从内存中的字节数组读取和写入。对于ByteArrayOutputStream
,当您将数据写入流时,数组会自动增长。
【讨论】:
ByteArrayInputStream
支持mark()
和reset()
在流中标记一个位置,以便您稍后可以跳回到那里。 ByteArrayOutputStream
没有这个。 Peter Lawrey 的建议,使用 NIO ByteBuffer
,可能更有用。
这是否允许在任何方向定位?
这些 ByteBuffers,我还不确定。问题是对非功能性需求的共同理解:频率、数据量和访问类型。取决于他们可能是一个好主意或坏主意。
所以最终的解决方案(没有随机定位)ByteArrayOutputStream inMemoryStream = new ByteArrayOutputStream(); /* write into stream */; ByteArrayInputStream inputStream = new ByteArrayInputStream(inMemoryStream.toByteArray()); /* read from the inputStream */
【参考方案2】:
是否需要支持输入和输出流?如果不是,我只会使用 ByteBuffer ,它允许您在随机位置读取/写入原始类型。 (最高 2 GB)
您可以在读取器和写入器之间共享一个 ByteBuffer。
例如
// 1 GB of virtual memory outside the heap.
ByteBuffer writer = ByteBuffer.allocateDirect(1024*1024*1024);
ByteBuffer reader = writer.slice();
您可以在线程(例如 Exchanger)和进程(使用内存映射文件)之间共享内存
【讨论】:
小尺寸如何使用?它会自动增长吗? 它不会自动增长。但是,如果您使直接缓冲区比您需要的大得多但您不使用它,则操作系统不会将内存分配给您的进程。 啊哈,好吧,我不知道。这在 OS 和 JVM 上是否得到保证? 是的,输入/输出是强制性的。这样我就可以插入现有的应用程序。 是的,应用程序实际上是通过 RandomAccessFile 而不是通过输入/输出流进行随机访问。但它从 RandomAccessFile 产生输入/输出流。但为了让事情不要太复杂,我发布了上面的接口规范。【参考方案3】:您可以使用 PipedInputStream 和 PipedOutputStream
像这样:
PipedOutputStream outstr = new PipedOutputStream();
PipedInputStream instr = new PipedInputStream(outstr);
这不会直接让您进行搜索,但它确实允许您从输入流中跳过任意数量的字节。
请注意,每当您写入 outstr 时,它都会被阻塞,直到从 instr 中读取所有内容(也就是说:如果我没记错的话,Streams 不会缓冲,但您可以用 BufferedInputStream 装饰它们,那么您就不会不得不打扰。
【讨论】:
【参考方案4】:NIO 允许您直接在内核内存中传输数据——我不确定它是否与 .NET 的内存流完全重叠。 Here's 一个将整个文件映射到内存中以供读取的简单示例。
【讨论】:
您能否将外部链接中的代码添加到您的答案中?以上是关于Java中的内存流的主要内容,如果未能解决你的问题,请参考以下文章