Java nio 學習筆記(三)

實現一:使用nio實現文件複製

package study.nio;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.ByteBuffer;
public class TestCopyFile {
	public static void main(String[] args) throws IOException {
		//調用FileManager類的copyFile靜態方法
		FileManager.copyFile(new File("src.txt"), new File("dst.txt"));
	}
}
class FileManager {
	//把可能出現的異常拋給上層調用者處理
	public static void copyFile(File src, File dst) 
			throws FileNotFoundException, IOException {
		//得到一個源文件對應的輸入通道
		FileChannel fcin = new FileInputStream(src).getChannel();
		//得到一個目標文件對應的輸出通道
		FileChannel fcout = new FileOutputStream(dst).getChannel();
		//生成一個1024字節的ByteBuffer實例
		ByteBuffer buf = ByteBuffer.allocate(1024);
		while(fcin.read(buf) != -1) {
			buf.flip();		//準備寫
			fcout.write(buf);
			buf.clear();		//準備讀
		}
	}
	
}

還可以使用下面方式進行操作,在FileChannel中有兩個特殊方法可以允許我們直接將兩個通道相連:

long transferFrom(ReadableByteChannel src, long position, long count);

long transferTo(long position, long count, WriteableByteChannel targets);

上面while循環可以替換爲:

fcin.transferTo(0, fcin.size(), fcout); 或者 fcout.transferFrom(fcin, 0, fcin.size());

 

實現二:向一個空文件中寫入some text,再以只讀方式打開該文件,在尾部追加some more,最終將該文件內容輸出。

package study.nio;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

public class GetChannel {
	//爲了使代碼明晰,暫不處理異常
	public static void main(String[] args) throws Exception {
		FileChannel fc = null;
		//向一個文件中寫入文本
		fc = new FileOutputStream(new File("data.txt")).getChannel();
		fc.write(ByteBuffer.wrap("some text".getBytes()));
		fc.close();
		//以讀寫方式打開文件,並在尾部追加內容
		fc = new RandomAccessFile("data.txt", "rw").getChannel();
		fc.position(fc.size());
		fc.write(ByteBuffer.wrap("some more".getBytes()));
		fc.close();
		//將文件裏的內容讀出來
		fc = new FileInputStream("data.txt").getChannel();
		ByteBuffer buf = ByteBuffer.allocate(1024);
		fc.read(buf);
		buf.flip();
		while(buf.hasRemaining()) {
			System.out.print((char)buf.get());
		}		
	}
}


 

以上均使用的是字節操作流,與nio相一致。Reader和Writer這些字符模式類不能用於產生通道,但是java.nio.channels.Channels類中提供了實用方法,可以在通道中產生Reader和Writer。

       Channels.newReader();

       Channels.newWriter();

實現三:將一個大文件映射到內存並查找指定的文本內容是否在該文件中(曾記得李開復與微軟的故事,當然李開復是從郵件中查找信息,並且郵件被截成了圖片,⊙﹏⊙b汗)

 

public class LargeMappedFiles {
    public static void main(String args[]) {   
        try {
        	File[] files = new File[] {new File("src1.txt"), new File("src2.txt")}; 
          ArrayList<String> ls = search(files, "something is wrong");
          for(int i=0; i<ls.size(); i++) {
          	System.out.println(ls.get(i));
          }
        } catch (FileNotFoundException e) {   
            e.printStackTrace();   
        } catch (Exception e) {   
            e.printStackTrace();   
        }   
    }
    //實現簡單的內容檢索
    private static ArrayList<String> search(File[] files, String text) throws Exception {
    	//把檢索結果放到一個list中
    	ArrayList<String> result = new ArrayList<String>();
    	//循環遍歷文件
    	for(File src : files) {
    		//將整個文件映射到內存
    		MappedByteBuffer dst = new RandomAccessFile(src, "rw")
            .getChannel()   
            .map(FileChannel.MapMode.READ_WRITE, 0, src.length());
        //對字符進行解碼
        String str = Charset.forName("UTF-8").decode(dst).toString();
        //準備進行讀
        dst.flip();
        if(str.indexOf(text) != -1) {
        	result.add(src.getName());
        }
        //準備寫
        dst.clear();
    	}
    	return result;
    }
}


 

實現四:在前面的學習中瞭解到nio爲所有原始數據類型提供了Buffer支持,並且在ByteBuffer中實現了asXBuffer()方法直接將一個ByteBuffer轉換成其它類型的Buffer。本例實現數據類型的轉換。

import java.nio.IntBuffer;
import java.nio.FloatBuffer;
import java.nio.ByteBuffer;
import java.util.Arrays;

public class CastBuffer {
	static byte[] bytes = new byte[] {0, 1, 2, 3, 4, 5, 'a', 'b', 'c'};
		
	public static void main(String[] args) {
		ByteBuffer bBuf = ByteBuffer.wrap(bytes);
		System.out.println(Arrays.toString(bBuf.array()));
		//轉換成IntBuffer
		IntBuffer iBuf = ((ByteBuffer)bBuf.rewind()).asIntBuffer();
		while(iBuf.hasRemaining()) {
			System.out.print(iBuf.get()+",");
		}
		//轉換成FloatBuffer
		FloatBuffer fBuf = ((ByteBuffer)bBuf.rewind()).asFloatBuffer();
		while(fBuf.hasRemaining()) {
			System.out.print(fBuf.get()+",");
		}
	}
}


 

其它類型轉換與上面方法類似,各種方法都相似。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章