亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java NIO(四)--FileChannel

2019-11-06 06:11:23
字體:
來源:轉載
供稿:網友

一、概述

NIO 中FileChannel可以理解為一個連接到文件的通道,可以通過FileChannel對文件進行讀寫; FileChannel沒有非阻塞模式,讀寫都只有阻塞的方式;

二、操作

打開FileChannel 

在使用FileChannel之前,必須先打開它。但是,我們無法直接打開一個FileChannel,需要通過使用一個InputStream、OutputStream或RandomaccessFile來獲取一個FileChannel實例。下面是通過RandomAccessFile打開FileChannel的示例: 

RandomAccessFile fromFile = new RandomAccessFile("D:/fromFile.txt", "rw");//獲取channelFileChannel fromChannel = fromFile.getChannel();

從FileChannel讀取數據 

首先,分配一個Buffer。從FileChannel中讀取的數據將被讀到Buffer中。 然后,調用FileChannel.read()方法。該方法將數據從FileChannel讀取到Buffer中。read()方法返回的int值表示了有多少字節被讀到了Buffer中。如果返回-1,表示到了文件末尾。如:
ByteBuffer buf = ByteBuffer.allocate(1024*4);  int bytesRead = inChannel.read(buf);  

向FileChannel寫數據 

使用FileChannel.write()方法向FileChannel寫數據,該方法的參數是一個Buffer。如:
String newData = "New String to write to file..." + System.currentTimeMillis();    ByteBuffer buf = ByteBuffer.allocate(1024*4);  buf.clear();  buf.put(newData.getBytes());    buf.flip();    while(buf.hasRemaining()) {      channel.write(buf);  }  注意FileChannel.write()是在while循環中調用的。因為無法保證write()方法一次能向FileChannel寫入多少字節,因此需要重復調用write()方法,直到Buffer中已經沒有尚未寫入通道的字節。 

關閉FileChannel 

用完FileChannel后必須將其關閉。如: 
channel.close();  

FileChannel的position方法 

有時可能需要在FileChannel的某個特定位置進行數據的讀/寫操作??梢酝ㄟ^調用position()方法獲取FileChannel的當前位置。 也可以通過調用position(long pos)方法設置FileChannel的當前位置。 這里有兩個例子: 
long pos = channel.position();  channel.position(pos +123);  如果將位置設置在文件結束符之后,然后試圖從文件通道中讀取數據,讀方法將返回-1 —— 文件結束標志。 如果將位置設置在文件結束符之后,然后向通道中寫數據,文件將撐大到當前位置并寫入數據。這可能導致“文件空洞”,磁盤上物理文件中寫入的數據間有空隙。 

FileChannel的size方法 

FileChannel實例的size()方法將返回該實例所關聯文件的大小。如: 
long fileSize = channel.size();  

FileChannel的truncate方法 

可以使用FileChannel.truncate()方法截取一個文件。截取文件時,文件將中指定長度后面的部分將被刪除。如:
channel.truncate(1024);  這個例子截取文件的前1024個字節。 

FileChannel的force方法 

FileChannel.force()方法將通道里尚未寫入磁盤的數據強制寫到磁盤上。出于性能方面的考慮,操作系統會將數據緩存在內存中,所以無法保證寫入到FileChannel里的數據一定會即時寫到磁盤上。要保證這一點,需要調用force()方法。 force()方法有一個boolean類型的參數,指明是否同時將文件元數據(權限信息等)寫到磁盤上。 下面的例子同時將文件數據和元數據強制寫到磁盤上: 
channel.force(true);  

示例

對于資源文件,操作完都是需要關閉的;以下是一個完成讀寫實例代碼:
public static void main(String[] args) throws IOException {	RandomAccessFile fromFile = new RandomAccessFile("src//a.txt", "rw");	RandomAccessFile toFile = new RandomAccessFile("src//b.txt", "rw");	// 獲取channel	FileChannel fromChannel = fromFile.getChannel();	FileChannel toChannel = toFile.getChannel();	// 定義緩沖大小	int bufSize = 1024 * 4;	// 定義緩沖	ByteBuffer byteBuffer = ByteBuffer.allocate(bufSize);	int len = 0;	// 將數據從源channel寫入到緩沖區	while ((len = fromChannel.read(byteBuffer)) != -1) {		// 切換到讀模式		byteBuffer.flip();		while (byteBuffer.hasRemaining()) {			// 讀取緩沖區數據寫到目標channel			toChannel.write(byteBuffer);		}		// 清空緩沖		byteBuffer.clear();	}	// 釋放資源	toChannel.close();	fromChannel.close();	toFile.close();	fromFile.close();}緩沖區的hasRemainning方法返回一個boolean,標識緩沖區中是否還有數據沒有讀取,寫入FileChannel必須在一個循環中,因為write方法無法保證緩沖區的數據一次全部寫入;

通過FileChannel直接傳輸

在兩個通道間傳輸數據,如果其中有一個是FileChannel,可以不使用緩沖區讀出、寫入的方式進行傳輸,可以使用FileChannel的transferFrom 和 transferTo 方法;

1. transferFrom

public long transferFrom(ReadableByteChannel src, long position, long count) throws IOException; 該方法可以從其他通道直接將數據傳輸到fileChannel,position參數表示從position開始先目標文件寫入數據,count參表示最多寫入的數據量,但是不一定會寫入這個參數的數據量,如果來源通道沒有那么多可讀數據的話;該方法返回一個long值表示成功寫入通道的數據量;

2. transferTo

public abstract long transferTo(long position, long count, WritableByteChannel target) throws IOException; 改方法與transferFrom相反,是將FileChannel的數據直接寫入到目標通道,position參數表示從position位置開始讀取數據寫入,count參數表示要寫入數據的大小,但是不一定寫入這個參數的數據量,如果這個fileChannel沒有那么多數據可以讀取的話;該方法返回一個long值,表示實際寫入目標通道的數據量;以下是一個通過transferFrom/transferTo方法復制文件的實例代碼:
public static void main(String[] args) throws IOException {        RandomAccessFile fromFile = new RandomAccessFile("src//a.txt", "rw");        RandomAccessFile inFile = new RandomAccessFile("src//a.txt", "rw");        FileChannel fromChannel = fromFile.getChannel();        FileChannel inChannel = inFile.getChannel();        int position = 0;        long count = fromChannel.size();        long successCount = inChannel.transferFrom(fromChannel, position, count);        //long successCount = fromChannel.transferTo(position, count, inChannel);        System.out.PRintln(successCount);    }

文件鎖定

FileChannel的鎖,與一般的對象鎖相似,都是勸告式鎖;獲取鎖后,它不阻止任何形式的數據訪問,而是與對象鎖相似,程序中可以通過它進行多線程間協調(線程安全處理);

通過FileChannel的lock方法,可以鎖定整個文件或指定一部分;         請求獲取的鎖有兩種:共享鎖和排它鎖;共享鎖可以獲取多個,而排它鎖只能獲取到一個;由于不同的操作系統對文件系統鎖的實現方式不一樣,有些實現了共享鎖,而另外一些只實現了排它鎖;

以下是一個獲取文件鎖的實例代碼,可以通過同時運行多個觀察效果:

public static void main(String[] args) throws Exception {        RandomAccessFile fromFile = new RandomAccessFile("src//a.txt", "rw");        FileChannel fromChannel = fromFile.getChannel();        System.out.println("trying to lock file...");        int start = 0;        int end = 10;        FileLock fileLock = fromChannel.lock(start, end, false);        System.out.println("after lock");        System.out.println("pause...");        Thread.sleep(8000);        System.out.println("releasing file lock");        fileLock.release();        System.out.println("after release.");        fromChannel.close();        fromFile.close();    }lock 方法中,start、end參數指定鎖定文件的部分,第三個boolean參數,true:表示獲取共享鎖,false:表示獲取排它鎖; 還有一個lock()無參的方法,實際是調用:

public final FileLock lock() throws IOException {        return lock(0L, Long.MAX_VALUE, false);}由于不是全部操作系統都支持共享鎖,所以就算請求獲取共享鎖,但是也可能會返回一個排它鎖,可以通過isShare方法確定鎖類型:
fileLock.isShared();對此,我們不如直接只使用排它鎖,而不是進行isShare邏輯的判斷。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美综合在线第二页| 国产精品福利在线观看网址| 久久久久久久久久久网站| 黑人狂躁日本妞一区二区三区| 欧美一级片在线播放| 久久久精品美女| 亚洲国产成人爱av在线播放| 久久国产色av| 国产精品爽爽爽爽爽爽在线观看| 国产91精品黑色丝袜高跟鞋| 亚洲欧美日韩高清| 国产精品黄页免费高清在线观看| 国产欧美日韩免费| 国产欧美久久一区二区| 欧美人与物videos| 欧美中文字幕精品| 欲色天天网综合久久| 欧美亚洲另类激情另类| 国产精品福利观看| 最近更新的2019中文字幕| 北条麻妃在线一区二区| 亚洲xxx自由成熟| 欧美日韩免费在线| 亚洲四色影视在线观看| www.日本久久久久com.| 精品亚洲国产视频| 538国产精品一区二区在线| 亚洲男人的天堂网站| 国产精品视频地址| 8x海外华人永久免费日韩内陆视频| 亚洲综合日韩中文字幕v在线| 国产成人极品视频| 日韩一区二区久久久| 欧美日韩激情网| 中文字幕久久久| 亚洲大尺度美女在线| 午夜免费在线观看精品视频| 久久久久久久999| 日韩av影院在线观看| 国产成人91久久精品| 亚洲最大福利网站| 久久久精品久久久| 日韩中文av在线| 亚洲色图在线观看| 亚洲人成自拍网站| 精品香蕉在线观看视频一| 国产成人高清激情视频在线观看| 中文字幕亚洲无线码在线一区| 欧美亚洲成人免费| 亚洲综合中文字幕68页| 亚洲一区二区自拍| 欧美在线激情视频| 欧美激情极品视频| 精品自拍视频在线观看| 大胆欧美人体视频| 久久久国产影院| 日韩欧美亚洲成人| 亚洲福利视频专区| 精品久久久久人成| 亚洲精品白浆高清久久久久久| 日韩av在线看| 91精品视频免费看| 欧美多人乱p欧美4p久久| 国内精品久久久久久影视8| 亚洲女在线观看| 欧美精品videos另类日本| 中文字幕亚洲欧美日韩2019| 夜夜嗨av一区二区三区免费区| 国产精品久久久精品| 自拍偷拍亚洲欧美| 国产精品久久久久av| 亚洲国产成人91精品| 亚洲精品国产精品久久清纯直播| 久久精品国产欧美亚洲人人爽| 亚洲欧洲美洲在线综合| 97免费在线视频| 欧美日韩国产丝袜另类| 91精品国产综合久久男男| 日韩电影第一页| 日韩亚洲在线观看| 国产精品999999| 亚洲国产欧美久久| 亚洲午夜性刺激影院| 91久久国产综合久久91精品网站| 国产精品久久在线观看| 亚洲老司机av| 91在线|亚洲| 精品久久久91| 国产精品爽爽爽| 日韩成人在线网站| 亚洲视频专区在线| 中文字幕日韩欧美在线视频| 色妞在线综合亚洲欧美| 中文字幕在线精品| 日韩毛片在线观看| 国产午夜精品理论片a级探花| 亚洲欧美中文字幕| 欧美一区亚洲一区| 色樱桃影院亚洲精品影院| 国产99久久精品一区二区 夜夜躁日日躁| 日韩精品免费视频| 中文字幕国产精品| 九九九久久国产免费| 亚洲aⅴ男人的天堂在线观看| 日韩有码在线观看| 欧美日韩国产综合视频在线观看中文| 成人免费网站在线观看| 欧美激情一区二区三区久久久| 国产精品va在线| 国产精品久久久久久久久久99| 51精品在线观看| 亚洲jizzjizz日本少妇| 久久久久久久av| 日韩av一区二区在线| 免费av一区二区| 2021国产精品视频| 国产精品嫩草影院一区二区| 亚洲成人中文字幕| 欧美高清在线视频观看不卡| 狠狠做深爱婷婷久久综合一区| 亚洲色图综合网| 色诱女教师一区二区三区| 国产成人亚洲综合91| 色综合久久天天综线观看| 久久免费视频在线观看| 亚洲国产精品免费| 96sao精品视频在线观看| 精品久久久久人成| 91中文在线视频| 国产精品视频免费在线观看| 久久久久久久国产精品| 国产精品爽爽爽| 热门国产精品亚洲第一区在线| 亚洲精品视频二区| 久久天天躁狠狠躁夜夜av| 日韩欧美亚洲一二三区| www.国产精品一二区| 久久国产精品久久久久| 亚洲精品影视在线观看| 国产成人在线一区二区| 日韩亚洲在线观看| 日韩精品中文字幕在线观看| 国语对白做受69| 日韩视频欧美视频| 精品国产一区二区三区久久狼5月| 77777少妇光屁股久久一区| 丝袜美腿亚洲一区二区| 日韩av日韩在线观看| 欧美一级视频免费在线观看| 热久久美女精品天天吊色| 欧美激情精品久久久久久大尺度| 亚洲自拍在线观看| 欧美激情综合色| 亚洲自拍另类欧美丝袜| 欧美激情a∨在线视频播放| 久久久免费高清电视剧观看| 亚洲最大av网| 爽爽爽爽爽爽爽成人免费观看| 91精品啪在线观看麻豆免费| 九九精品在线视频| 国产欧美精品一区二区三区介绍| 精品久久久久久久久国产字幕| 黑人巨大精品欧美一区二区三区| 国内精品久久久久影院优|