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】:

ByteArrayInputStreamByteArrayOutputStream 是您要查找的内容。

这些是接口InputStreamOutputStream 的实现,它们从内存中的字节数组读取和写入。对于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中的内存流的主要内容,如果未能解决你的问题,请参考以下文章

输入流与输出流

java IO流 对象流的使用

Java流

Java学习IO流

java流汇总以及使用实例

JAVA学习之-I/O流