java NIO 中FileChannel 的實現類是 FileChannelImpl,FileChannel本身是一個抽象類。
先介紹FileChannel
File Channels 是線程安全的。Channel的close方法可以隨時執行(正如Channel接口所要求的)。任何企圖修改filechannel 對應文件大小 或者修改 filechannel position的操作都必須串行執行,第二個操作會一直阻塞直到前一個運行完。不過這些方法,具體還要看如何實現。(下文分析FileChannelImpl)。
創建FileChannel 實例可以通過執行FileChannel的一些方法,比如open方法,或者通過java.io.FileInputStream、java.io.FileOutputStream、java.io.RandomAccessFile的getchannel() 。(ps:網上說RandomAccessFile默認就獲取了文件鎖,但是我在官網api和RandomAccessFile.java中並未發現相關說明和代碼,有人知道是怎么回事的話望不吝賜教,目前我對網上的觀點持懷疑態度。)如果使用getChannel獲取的FileChannel的話,FileChannel就與FileInputStream或FileOutputStream等對象,產生了關聯(后文在分析為何會這樣)。也就是說比如當前新建一個FileInputStream對象,然后獲取一個FileChannel,此時position是0,然后FileInputStream讀取了100字節,讀完之后,FIleInputStream下次肯定會從第101個字節讀取,這是顯而易見的,但是你剛才獲取的Channel的position也會移動100。有代碼為證:
FileInputStream inputstream = new FileInputStream(sourceFile);
byte[] buffer = new byte[100];
ByteBuffer bb = ByteBuffer.allocate(1024);
FileChannel channel = inputstream.getChannel();
System.out.println("channel "+channel.position());
int read=inputstream.read(buffer);
System.out.println("channel "+channel.position()+" read "+read);
輸出結果:
channel 0
channel 100 read 100
繼續。FileChannel打開模式有 讀、寫 和 讀and寫。FileInputStream獲取的自然是讀.OutputStream自然是寫,RandomAccessFile就看你的RandomAccessFile是何種模式。
FileChannel的追加模式(append-mode)是由所使用的FileOutputStream決定的。追加模式時先跳到文件末尾再開始寫,這個操作的原子性是由操作系統支持(FileChannel.java 中的原文 Whether the advancement of the position and the writing of the data are done in a single atomic operation is system-dependent and therefore unspecified)。