天天看點

java nio 異步操作 (一)

先來看些nio基礎的類庫關系圖 用pd大緻畫了下

java nio 異步操作 (一)
java nio 異步操作 (一)

相關的圖檔

java nio 異步操作 (一)
java nio 異步操作 (一)

檔案通道  filechannel

多路複用器  selector

服務端

package com.undergrowth;  

import java.io.bufferedreader;  

import java.io.ioexception;  

import java.io.inputstreamreader;  

import java.net.inetsocketaddress;  

import java.net.socket;  

import java.nio.channels.selectionkey;  

import java.nio.channels.selector;  

import java.nio.channels.serversocketchannel;  

import java.util.iterator;  

import java.util.set;  

import org.junit.after;  

import org.junit.before;  

import org.junit.test;  

/** 

 * 測試多路複用器 selector 

 * @author u1 

 * 

 */  

public class basicselector {  

    //多路複用器  檢測7777和8888端口  

    private selector selector;  

    private serversocketchannel channel7777,channel8888;  

    @before  

    public void before() throws ioexception{  

        selector=selector.open();  

        //打開7777端口服務通道  

        channel7777=serversocketchannel.open();  

        //綁定7777端口的服務監聽  

        channel7777.socket().bind(new inetsocketaddress(7777));  

        //配置為非阻塞模式  

        channel7777.configureblocking(false);  

        //将通道注冊到多路複用器上  

        channel7777.register(selector,  selectionkey.op_accept);  

        //打開8888端口服務通道  

        channel8888=serversocketchannel.open();  

        //綁定8888端口的服務監聽  

        channel8888.socket().bind(new inetsocketaddress(9999));  

        channel8888.configureblocking(false);  

        //關注讀操作  

        channel8888.register(selector, selectionkey.op_accept);  

    }  

    /** 

     * 關閉資源 

     * @throws ioexception 

     */  

    @after  

    public void after() throws ioexception{  

        selector.close();  

        channel7777.close();  

        channel8888.close();  

    @test  

    public void select() throws ioexception{  

        //控制循環  

        bufferedreader reader=new bufferedreader(new inputstreamreader(system.in));  

        while(true){  

            system.out.println("是否還要進行");  

            string isgostring=reader.readline();  

            if("n".equalsignorecase(isgostring)) break;  

            system.out.println("等待事件源發生");  

            //等待注冊的事件源發生  

            int readychannel=selector.select();  

            if(readychannel==0) continue;  

            system.out.println("有"+readychannel+"個準備好了");  

            //擷取準備好的通道  

            set<selectionkey> selectionkeys=selector.selectedkeys();  

            iterator<selectionkey> selectkeyiterator=selectionkeys.iterator();  

            while (selectkeyiterator.hasnext()) {  

                selectionkey selectionkey = (selectionkey) selectkeyiterator  

                        .next();  

                //周遊注冊中準備好的事件源  

                interestset(selectionkey.interestops());  

                if(selectionkey.isacceptable()){  

                    //當用戶端進行連接配接時  擷取socket  會寫資訊  

                    serversocketchannel serversocketchannel=(serversocketchannel) selectionkey.channel();  

                    system.out.println(serversocketchannel.socket().getlocalport()+"端口\t"+"感興趣的操作:"+serversocketchannel.validops());  

                    socket socket=serversocketchannel.socket().accept();  

                    socket.getoutputstream().write("從selector中傳回給用戶端".getbytes());  

                    socket.getoutputstream().flush();  

                    socket.close();  

                }  

                //移除已經處理的事件源  

                selectkeyiterator.remove();  

            }  

        }  

     * 周遊注冊中準備好的事件源 

     * @param interestops 

    private void interestset(int interestset) {  

        // todo auto-generated method stub  

        if((interestset&selectionkey.op_accept)!=0) system.out.println("注冊的可接受");  

        if((interestset&selectionkey.op_connect)!=0) system.out.println("注冊的可連接配接");  

        if((interestset&selectionkey.op_read)!=0) system.out.println("注冊的可讀");  

        if((interestset&selectionkey.op_write)!=0) system.out.println("注冊的可寫");  

}  

用戶端

java nio 異步操作 (一)

 * 連接配接服務serversocket 

public class basicsocketchannel {  

     * @param args 

     * @throws ioexception  

    public static void main(string[] args) throws ioexception {  

        //用于用戶端的socket連接配接 測試  

        socket socket=new socket();  

        socket.connect(new inetsocketaddress(7777));  

        bufferedreader reader=new bufferedreader(new inputstreamreader(socket.getinputstream()));   

        system.out.println("讀取的字元串為:"+reader.readline());  

路徑   path與paths

java nio 異步操作 (一)

import java.nio.file.path;  

import java.nio.file.paths;  

 * a java path instance represents a path in the file system. a path can point 

 * to either a file or a directory. a path can be absolute or relative. an 

 * absolute path contains the full path from the root of the file system down to 

 * the file or directory it points to. a relative path contains the path to the 

 * file or directory relative to some other path. 

 *  

public class basicpath {  

     * 測試絕對路徑 

    public void testabsolute() {  

        path path=paths.get("e:\\book", "java_api_1.7中文.chm");  

        system.out.println(path.tostring());  

     * 測試相對路徑 

     * .---->目前路徑 

     * ..---->父路徑 

    public void testrelative(){  

        path path=paths.get(".");  

        system.out.println(path.toabsolutepath());  

        path=paths.get("..");  

     * 格式化path路徑  

     * 去除.和.. 

    public void testnormalize(){  

        path path=paths.get("e:\\book\\weblogic\\.\\51cto下載下傳-oracle weblogic server開發權威指南.part1.rar");  

        system.out.println(path.normalize().toabsolutepath());  

        path=paths.get("e:\\book\\..\\");  

管道  pipe

java nio 異步操作 (一)

import java.nio.bytebuffer;  

import java.nio.channels.pipe;  

 * 管道操作 

 * a java nio pipe is a one-way data connection between two threads. a pipe has 

 * a source channel and a sink channel. you write data to the sink channel. this 

 * data can then be read from the source channel 

public class basicpipe {  

    pipe pipe;  

    pipe.sinkchannel writepipe;  

    pipe.sourcechannel readpipe;  

    bytebuffer buffer;  

        pipe=pipe.open();  

        writepipe=pipe.sink();  

        readpipe=pipe.source();  

        buffer=bytebuffer.allocate(1024);  

    public void testpipe() throws ioexception{  

        string string="通過管道進行傳輸資料";  

        buffer.put(string.getbytes());  

        buffer.flip();  

        //将資料寫入接受的通道中  

        while(buffer.hasremaining()) writepipe.write(buffer);  

        //将資料從讀的通道中讀出  

        bytebuffer bytebuffer=bytebuffer.allocate(1024);  

        stringbuilder builder=new stringbuilder();  

        int readbyte=readpipe.read(bytebuffer);  

        bytebuffer.flip();  

        byte[] dst=new byte[bytebuffer.limit()];  

        bytebuffer.get(dst);  

        builder.append(new string(dst));  

        bytebuffer.clear();  

        system.out.println("從讀的通道中讀出的資料為:"+builder.tostring());  

檔案  files

java nio 異步操作 (一)

import static org.junit.assert.*;  

import java.nio.file.filevisitresult;  

import java.nio.file.filevisitor;  

import java.nio.file.files;  

import java.nio.file.linkoption;  

import java.nio.file.simplefilevisitor;  

import java.nio.file.standardcopyoption;  

import java.nio.file.attribute.basicfileattributes;  

 * the java nio files class (java.nio.file.files) provides several methods for 

 * manipulating files in the file system. 

 * 檔案操作類 

 *    建立兩個檔案夾 再将檔案複制到兩檔案夾中 然後進行周遊檔案樹 周遊完成後 删除檔案夾及檔案 

public class basicfiles {  

    public void test() throws ioexception {  

        //擷取路徑  

        path path=paths.get(".\\test");  

        //分别建立兩個檔案夾 在test裡面 分别為test1 和  test2  

        createdir(path);  

        //複制檔案  

        copyfiles(path);  

        //周遊檔案  

        path=paths.get(".\\test");  

        walkfile(path);  

     * 周遊檔案目錄 

     * @param path 

    private void walkfile(path path) throws ioexception {  

        files.walkfiletree(path, new simplefilevisitor<path>(){  

            @override  

            public filevisitresult visitfile(path file,  

                    basicfileattributes attrs) throws ioexception {  

                // todo auto-generated method stub  

                //删除檔案  

                system.out.println("删除"+file.tofile().getabsolutepath());  

                files.delete(file);  

                return filevisitresult.continue;  

            public filevisitresult postvisitdirectory(path dir, ioexception exc)  

                    throws ioexception {  

                //周遊完目錄後删除  

                system.out.println("周遊完目錄後删除"+dir.toabsolutepath());  

                files.delete(dir);  

        });  

     * 複制檔案 

    private void copyfiles(path path) throws ioexception {  

        path pathsource =paths.get("..\\git.txt");  

        path=paths.get(".\\test\\test1\\git.txt");  

        //替換已經存在的檔案  

        files.copy(pathsource, path,standardcopyoption.replace_existing);  

        path=paths.get(".\\test\\test2\\git.txt");  

     * 建立檔案夾 

    private void createdir(path path) throws ioexception {  

        if(!files.exists(path, new linkoption[]{linkoption.nofollow_links}))  

            files.createdirectories(path);  

        path=paths.get(path.tostring(), "test1");  

        path=paths.get(path.tostring(), "..\\test2");