一起去看海

2010/04/12

【每日一技】提高文件读取速度的NIO

Filed under: Dian团队, Java笔记 — Tags: , — admin @ 17:19

NIO即new io.主要是采用通道机制来提高文件读取速度。以下为一个简单的读取文本文
件的例子:

[java]public String readTxtFile(String path) throws IOException {

long start = System.currentTimeMillis();

//设置缓冲区的大小

final int BUFFER_SIZE = 0×900000;

String content = "";

// 创建一个文件输入流

FileInputStream fis = new FileInputStream(path);

// 获得该输入流的通道

FileChannel fc = fis.getChannel();

// 创建一个字节缓冲区

ByteBuffer bb = ByteBuffer.allocate(BUFFER_SIZE);

// 将字节序列从此通道读入给定的缓冲区

fc.read(bb);

// 反转此缓冲区。首先将限制设置为当前位置,然后将位置设置为 0

bb.flip();

// 获得缓冲区中剩余元素数,并创建相应的字节数组

byte[] bytes = new byte[bb.remaining()];

// 将缓冲区中的字节序列存放在字节数组里

bb.get(bytes);

// 将字节数组中的内容转换成字符串

content = new String(bytes);

long end = System.currentTimeMillis();

System.out.println(end – start);

return content;

}[/java]

我做了一个简单的测试,对于一般几K到几十K的文本文件,只需要几毫秒到20几毫秒
,对于一个好几M的文本文件,只需要200多个毫秒。希望有兴趣的同学可以进一步的研
究,共同探讨相关话题。

另外推荐一篇关于流的文章:http://www.ibm.com/developerworks/cn/java/j-io1/

———————————————————

henix: 那跟FileInputStream再套上BufferedInputStream有什么区别?

———————————————————

spllot:

我觉得一个很重要的区别是,NIO中的做法更灵活,操作起来比较简单.我写的小例子只是
其中的一角,还有像MappedByteBuffer等缓冲区,这些缓冲区都有清除、反转和重绕方法
,用以标记当前位置,以及将当前位置重置为前一个标记处.并且还定义了一系列用于将
数据移出或移入缓冲区的 get 和 put 方法,用于压缩、复制 和切片 缓冲区的方法,
以及用于分配新缓冲区和将现有数组包装到缓冲区中.

对于我写的那个小程序,确实给人的感觉是空间换时间.

就我写的那个程序来说,对于一个小的文件,缓冲区设置小一点是没有什么问题的,但是如
果是一个好几个M的文件,如果缓冲区设置的过小的话,会出现读出来的内容不完全的情况
.所以为了简单的引进NIO,我仅仅是做了一个示例.

对于文件比较大的情况,如果将缓冲区设置比较小的话,也是可以解决的,分块来读就行了
.NIO是按块来读的,从这点来看,就比传统的IO读起来会快很多.另外NIO是无阻塞的,传统
的IO读文件的时候,需要将数据读到缓冲区后,再等待处理,会浪费很多时间,但NIO则不需
要,通过通道来传输,减少了等待的时间,从而提高了读取速度.

P.S 我的毕业设计是桌面搜索引擎,其中会涉及到文件的读取,有可能文件是比较大的,并
且数量是比较多的,所以如何减少读取时间,提高索引速度是很重要的,因此我考虑到使用
NIO.有兴趣的同学可以和我一起研究.

—————————————————

转自Dian团队内部技术讨论。

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress