彻底转变流,第1部分 - 编程入门网
决的问题。
彻底转变流,第1部分(2)时间:2011-06-21 Merlin Hughes蛮力解决方案 在着手寻找解决我问题的工程方案前,我根据标准 Java API 类的精致和有 效性,研究了基于这些类的解决方案。 该问题的蛮力解决方案就是简单地从输入源中读取所有数据,然后通过转换 程序(即,压缩流、编码流或 XML 序列化器)将它们推进内存缓冲区中。然后 ,我可以从该内存缓冲区中打开要读取的流,这样我就解决了问题。 首先,我需要一个通用的 I/O 方法。清单 1 中的方法利用一个小缓冲区将 InputStream 中的所有数据复制到 OutputStream 。当到达输入的结尾( read () 函数的返回值小于零)时,该方法就返回,但不关闭这两个流。 清单 1. 通用的 I/O 方法
清单 2 显示蛮力解决方案如何使我读取压缩格式的输入流。我打开写入内存 缓冲区的 GZIPOutputStream (使用 ByteArrayOutputStream )。接着,将输 入流复制到压缩流中,这样将压缩数据填入内存缓冲区中。然后,我返回 ByteArrayInputStream ,它让我从输入流中读取,如图 2 所示。 图 2. 蛮力解决方案 清单 2. 蛮力解决方案
这个解决方案有一个明显的缺点,它将整个压缩文档都存储在内存中。如果 文档很大,那么这种方法将不必要地浪费系统资源。使用流的主要特性之一是它 们允许您操作比所用系统内存要大的数据:您可以在读取数据时处理它们,或在 写入数据时生成数据,而无需始终将所有数据保存在内存中。 彻底转变流,第1部分(3)时间:2011-06-21 Merlin Hughes从效率上,让我们对在缓冲区之间复制数据进行更深入研究。 通过 io() 方法,将数据从输入源读入至一个缓冲区中。然后,将数据从缓 冲区写入 ByteArrayOutputStream 中的缓冲区(通过我忽略的压缩过程)。然 而, ByteArrayOutputStream 类对扩展的内部缓冲区进行操作;每当缓冲区变 满时,就会分配一个大小是原来两倍的新缓冲区,接着将现有的数据复制到该缓 冲区中。平均下来,这一过程每个字节复制两次。(算术计算很简单:当进入 ByteArrayOutputStream 时,对数据平均复制两次;所有数据至少复制一次;有 一半数据至少复制两次;四分之一的数据至少复制三次,依次类推。)然后,将 数据从该缓冲区复制到 ByteArrayInputStream 的一个新缓冲区中。现在,应用 程序可以读取数据了。总之,这个解决方案将通过四个缓冲区写数据。这对于估 计其它技术的效率是一个有用的基准。 管道式流解决方案 管道式流 PipedOutputStream 和 PipedInputStream 在 Java 虚拟机的线程 之间提供了基于流的连接。一个线程将数据写入 PipedOutputStream 中的同时 ,另一个线程可以从相关联的 PipedInputStream 中读取该数据。 就这样,这些类提供了一个针对我问题的解决方案。清单 3 显示了使用一个 线程通过 GZIPOutputStream 将数据从输入流复制到 PipedOutputStream 的代 码。然后,相关联的 PipedInputStream 将提供对来自另一个线程的压缩数据的 读取权,如图 3 所示: 图 3. 管道式流解决方案 清单 3. 管道式流解决方 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |