天天看点

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");