java1.4引入了java.nio.*包诸典,大大提高了讀寫速度荠列。
一.讀寫速度對(duì)比
內(nèi)存映射文件 > 帶緩沖的流 > 普通輸入流 > 隨機(jī)訪問文件(RandomAccessFile
)
二.速度為什么會(huì)提升?
新I/O所使用的的結(jié)構(gòu)更接近操作系統(tǒng)執(zhí)行I/O的方式:通道和緩沖器师抄。
通道(類似流,但不能與數(shù)據(jù)直接交互,用于傳送用于讀寫的ByteBuffer
)只能與緩沖器(ByteBuffer
)進(jìn)行交互.
三.對(duì)舊I/O庫(kù)的修改
舊I/O庫(kù)中有三個(gè)類被修改涵但,用于產(chǎn)生FileChannel。
FileInputStream
FileChannel fc = new FileInputStream(filename).getChannel();
FileOutputStream
FileChannel fc = new FileOutputStream(filename).getChannel();
RandomAccessFile(隨機(jī)訪問文件,可以在文件任意位置同時(shí)讀寫)
FileChannel fc = new FileOutputStream(filename).getChannel();
四.將字節(jié)存放到ByteBuffer的方式
可以通過兩種方式將字節(jié)存放到ByteBuffer
- 使用put方法填入一個(gè)或多個(gè)字節(jié)帖蔓,或基本數(shù)據(jù)類型的值
- 使用wrap方法將數(shù)組“包裝”到ByteBuffer中
五.將字節(jié)從ByteBuffer中讀出的方式
- 緩沖器需要先顯式的使用allocate靜態(tài)方法(或allocateDirect方法矮瘟,下周學(xué)習(xí)差異)來分配ByteBuffer(分配空間后,空間內(nèi)容自動(dòng)置零)
ByteBuffer buff = ByteBuffer.allocate(BUFFERSIZE);
- FileChannel調(diào)用read來告知FileChannel向ByteBuffer存儲(chǔ)字節(jié)塑娇。
fc.read(buff);
- 緩沖器調(diào)用flip方法澈侠,同其做好讓別人讀取字節(jié)的準(zhǔn)備。
buff.flip();
- 調(diào)用read方法獲取緩沖器中的數(shù)據(jù),read方法讀到末尾時(shí)返回-1钝吮÷窠В可以使用hasRemaing方法查看是否存在未讀取的數(shù)據(jù)。
while(buff.hasRemaing())
System.out.println((Char)buff.get());
六.存取字符
ByteBuffer只能存取字節(jié)奇瘦,而使用CharBuffer可以對(duì)字符數(shù)據(jù)進(jìn)行存取
通過asCharBuffer可以將ByteBuffer轉(zhuǎn)換成CharBuffer
- 字符的存入
FileChannel fc = new FileOutputStream(filename).getChannel();
ByteBuffer buff = ByteBuffer.allocate(24);
buff.asCharBuffer().put("some text");
fc.write(buff);
fc.close();
字符的讀出
FileChannel fc = new FileInputStream(filename).getChannel();
ByteBuffer buff = ByteBuffer.allocate(24);
fc.read(buff);
buff.flip();
System.out.Println(buff.asCharBuffer());
緩沖器實(shí)際保存數(shù)據(jù)的結(jié)構(gòu)為ByteBuffer棘催,讀出為Char的時(shí)候可能會(huì)存在字符編碼集的問題,因此要保證讀出的字符數(shù)據(jù)不出現(xiàn)亂碼耳标,可以用下面三種方式對(duì)數(shù)據(jù)進(jìn)行處理:
- 向ByteBuffer寫入數(shù)據(jù)時(shí)指定字符編碼
fc.write(ByteBuffer.wrap("some text".getBytes("系統(tǒng)默認(rèn)編碼")));
- 從ByteBuffer讀出數(shù)據(jù)時(shí)指定字符編碼
Charset.forname("系統(tǒng)默認(rèn)編碼").decode(buff);
- 讀入和寫出都通過CharBuffer
七.存取基本數(shù)據(jù)類型
存入基本數(shù)據(jù)類型
ByteBuffer buff = ByteBuffer.allocate(SIZE);
buff.asCharBuffer().put("hello");
//buff.asShortBuffer().put((short)123);
//buff.asIntBuffer().put((short)123);
...
取出基本數(shù)據(jù)類型
buff.getChar();
//buff.getShort();
//buff.getInt();
...
八.試圖緩沖器
ByteBuffer是實(shí)際存儲(chǔ)數(shù)據(jù)的地方醇坝,但試圖緩沖器可以讓我們通過某個(gè)特定的基本數(shù)據(jù)類型查看底層的ByteBuffer
九.用緩沖器操作數(shù)據(jù)
我們可以通過試圖緩沖器將基本類型數(shù)據(jù)移入移除ByteBuffer,但不能直接將基本類型的緩沖器轉(zhuǎn)換成ByteBuffer
十.緩沖器的實(shí)現(xiàn)細(xì)節(jié)
緩沖器實(shí)現(xiàn)細(xì)節(jié)舉例和為什么新IO的實(shí)現(xiàn)方式能夠提升速度次坡,將在下周繼續(xù)學(xué)習(xí)