论坛首页 Java企业应用论坛

Java FileChannel 的使用體會

浏览 8131 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (11)
作者 正文
   发表时间:2010-05-17   最后修改:2010-05-17
今天看到一篇文章,說用NIO複製比較快。

原文是http://www.iteye.com/topic/667457

我就寫一篇關於FileChannel的文章吧,大家可以一起討論。

首先來看

public abstract long transferTo(long position,
                                long count,
                                WritableByteChannel target)
                         throws IOException
An attempt is made to read up to count bytes starting at the given position in this channel's file and write them to the target channel. An invocation of this method may or may not transfer all of the requested bytes; whether or not it does so depends upon the natures and states of the channels.Fewer than the requested number of bytes are transferred if this channel's file contains fewer than count bytes starting at the given position, or if the target channel is non-blocking and it has fewer than count bytes free in its output buffer.

This method is potentially much more efficient than a simple loop that reads from this channel and writes to the target channel. Many operating systems can transfer bytes directly from the filesystem cache to the target channel without actually copying them.

首先這個方法是一個attempt,意味著你可能得不到所有的byte。

綠色部分解釋了這個原因,首先這是個non-blocking的方法,遇到網絡或者其他方法,很容易得不到所有的byte而返回,此外,到底是阻塞還是非阻塞,還與文件的句柄本身有關,有文件設置為阻塞的,有些是非阻塞的,比如unix。

最下面的藍色部分,闡述了這個原理上更快的原因。

其實,transferTo method 實際上會先從 source channel 取得 MappedByteBuffer,然後在把 MappedByteBuffer 的內容傳輸到 destination channel上面。但是值得注意的是,這個操作不總是能夠成功,我在一台配置有 4G 內存的 Win7 上,沒有辦法去Map一個長度為2G的文件。會有exception:
java.io.IOException: Map failed
的異常,這點我目前是無法解釋的。

相反來說,BufferedReader可能原理上面沒有FileChannle快,但是非常穩定,並且速度上面並不遜於FileChnanel,主要是SUN對BufferedReader已經優化了無數次吧。

實際經驗而言,如果一次性COPY的數據大於MEM的1/4,我覺得還是使用BufferedReader,如果小一些的話,用FileChannel無疑最快,畢竟它還有一把FileLock,這是你多執行緒最佳選擇。


   发表时间:2010-05-18  
繁体?。。。。。。。
0 请登录后投票
   发表时间:2010-05-18  
看着贼不舒服!!!!!!!!!!!!!!
0 请登录后投票
   发表时间:2010-05-18  
这个台湾人写的吧 没个简体版吗 好多字看不懂哟
0 请登录后投票
   发表时间:2010-05-18  
文章写得不错,最后一句没看懂,搞个简体版的,大家可以一起讨论一下,很少见到繁体的帖子。Javaeye的人气不错。

beneo 写道
今天看到一篇文章,说用NIO复制比较快。

原文是http://www.iteye.com/topic/667457

我就写一篇关于FileChannel的文章吧,大家可以一起讨论。

首先来看

public abstract long transferTo(long position,
                                long count,
                                WritableByteChannel target)
                         throws IOException
An attempt is made to read up to count bytes starting at the given position in this channel's file and write them to the target channel. An invocation of this method may or may not transfer all of the requested bytes; whether or not it does so depends upon the natures and states of the channels.Fewer than the requested number of bytes are transferred if this channel's file contains fewer than count bytes starting at the given position, or if the target channel is non-blocking and it has fewer than count bytes free in its output buffer.

This method is potentially much more efficient than a simple loop that reads from this channel and writes to the target channel. Many operating systems can transfer bytes directly from the filesystem cache to the target channel without actually copying them.

首先这个方法是一个attempt,意味着你可能得不到所有的byte。

绿色部分解释了这个原因,首先这是个non-blocking的方法,遇到网络或者其他方法,很容易得不到所有的byte而返回,此外,到底是阻塞还是非阻塞,还与文件的句柄本身有关,有文件设置为阻塞的,有些是非阻塞的,比如unix。

最下面的蓝色部分,阐述了这个原理上更快的原因。

其实,transferTo method 实际上会先从 source channel 取得 MappedByteBuffer,然后再把 MappedByteBuffer 的內容传输到 destination channel上面。但是值得注意的是,这个操作不总是能够成功,我在一台配置有 4G 內存的 Win7 上,沒有办法去Map一个长度为2G的文件。会有exception:
java.io.IOException: Map failed
的异常,这点我目前是无法解释的。

相反来说,BufferedReader可能原理上面沒有FileChannle快,但是非常稳定定,並且速度上面并不逊于FileChnanel,主要是SUN对BufferedReader已经优化了无数次吧。

实际经验而言,如果一次性COPY的数据大于MEM的1/4,我觉得还是使用BufferedReader,如果小一些的话,用FileChannel无疑最快,毕竟它还有一把FileLock,这是你多执行绪最佳选择。



0 请登录后投票
   发表时间:2010-05-19  
daimojingdeyu 写道
文章写得不错,最后一句没看懂,搞个简体版的,大家可以一起讨论一下,很少见到繁体的帖子。Javaeye的人气不错。


FileLock 能够帮助你在JVM层面上面获得文件锁,换句话说,能够让你的Java程序独占这个文件的访问权限,但是不能保证Java程序内部的多线程访问情况。

所以在实际的多线程访问文件的过程中,如果要实现“线程安全”(这里的线程安全含义比较广),不但需要FileLock这个“外部”锁,防止其他“程序”访问这个文件,还需要一把“内部”锁,用来保证线程安全。

http://java.sun.com/javase/6/docs/api/java/nio/channels/FileLock.html
0 请登录后投票
   发表时间:2010-05-19  
这样的文章才不会误导观众
0 请登录后投票
   发表时间:2010-05-19  
以前没接触过,借此了解下,,,
0 请登录后投票
   发表时间:2010-05-20  
Java FileChannel 又不是用的你的机器内存,是用的虚拟机的内存空间,你机器内存再大也没用。
0 请登录后投票
   发表时间:2010-05-20  
ymcano11 写道
Java FileChannel 又不是用的你的机器内存,是用的虚拟机的内存空间,你机器内存再大也没用。


API上面说的是filesystem cache

所以这个cache应该不是heap or non-heap
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics