1. 程式人生 > >Java nio(檔案讀寫 例項解析)

Java nio(檔案讀寫 例項解析)

讀寫操作是I/O操作的基本行為;NIO中從Channel中讀資料非常簡單:建立一個buffer;通過一個channel完成buffer的資料讀入;寫資料同樣簡單:建立一個buffer;向其中填充資料;然後通過一個channel完成buffer的資料寫入;

下面通過java的實際例子進行說明:

NIO讀操作:

原來的IO中需要先建立一個FileInputStream然後完成讀操作;

NIO讀資料時因為資料最終都駐留在buffer,所以你只需要從channel中讀取資料到buffer物件中;

NIO中讀取資料的步驟:1)從FileInputStream中得到Channel物件;2)建立一個buffer

物件;3)Channel中讀資料到Buffer;

javaCode:

-------------------------------------------------------------------------------------------------------------------------

//FileInputStream中獲取channel物件

FileInputStream fis = new FileInputStream(new File("D://1.txt"));

FileChannel fc = fis.getChannel();

//生成一個偏移量為0,容量和最大容量都為

1024ByteBuffer

ByteBuffer bb = ByteBuffer.allocate(1024);

//fcbuffer中讀入資料

fc.read(bb);

--------------------------------------------------------------------------------------------------------------------------

你可能會注意到這裡我們並不需要要求channel物件讀入多少buffer資料,每個buffer物件內部有一個複雜的計數系統來跟蹤已經讀取的資料和剩餘可讀的buffer資料空間;

NIO

寫資料:

javacode:

--------------------------------------------------------------------------------------------------------------------------

//FileOutputStream中獲取一個檔案流;

FileOutputStream fos = new FileOutputStream("D:/1.txt");

FileChannel fc = fos.getChannel();

//建立一個buffer並把準備寫的資料填充進去;

ByteBuffer bb = ByteBuffer.allocate(1024);

//資料來源

byte[] message = {1,2,42,'a',3};

bb.put(message);

bb.flip();

//一定得有,如果沒有,就是從檔案最後開始讀取的。通過這個語句,就能把buffer的當前位置更改為buffer緩衝區的第一個位置。這樣就可以從buffer開頭,對該buffer進行遍歷(讀取)了。

//實際的寫操作;

fc.write(bb);-----------------------------------------------------------------

這裡同樣的,我們不需要告訴Channel物件我們將要寫入多少個位元組,buffer內部有自己的計數系統來跟蹤記錄已經包含的資料和還可以寫入資料的空間;

NIO的同時讀操作和寫操作:

舉一個CopyFile的例子:從一個檔案中複製資料到另一個檔案中;其中包含三個基本操作:

建立一個Buffer,然後從從一個原始檔中讀取資料到buffer,繼而把buffer中的資料寫入到目標檔案中; Read->Write->Read->Write;該過程一直重複直至完成複製;

所以核心的迴圈程式碼如下:

-----------------------------------------------------------------

fcin.read(buffer);//read

fout.write(buffer);//write

-----------------------------------------------------------------

控制的迴圈終點: int r = fcin.read(buffer);

if(r==-1) 可以作為迴圈控制的終點;

重新定位Buffer位置:

1)fcinbuffer讀資料之前,使用clear();

2)bufferfcout寫資料之前,使用flip;

-----------------------------------------------------------------

buffer.clear();

int r = fcin.read(buffer);

if(r==1){

break;

}

buffer.flip();

fcout.write(buffer);

-----------------------------------------------------------------

CopyFile.java全文:

-----------------------------------------------------------------

staticpublicvoid main( String args[] ) throws Exception {

if (args.length<2) {

System.err.println( "Usage: java CopyFile infile outfile" );

System.exit( 1 );

}

File file = new File("");

String infile = args[0];

String outfile = args[1];

FileInputStream fin = new FileInputStream( infile );

FileOutputStream fout = new FileOutputStream( outfile );

FileChannel fcin = fin.getChannel();

FileChannel fcout = fout.getChannel();

ByteBuffer buffer = ByteBuffer.allocate( 1024 );

while (true) {

buffer.clear();

int r = fcin.read( buffer );

if (r==-1) {

break;

}

buffer.flip();

fcout.write( buffer ); }

}

-----------------------------------------------------------------