使用NIO在网络上传输文件
来源:互联网 发布:开源网络行为管理 编辑:程序博客网 时间:2024/05/29 15:16
NIO,官方说法为New IO,我们也可以理解为Non Blocking IO。NIO需要JDK1.7以上支持。
package channel;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.Date;import java.util.Iterator;import java.util.Set;import org.junit.Test;public class TestNIO {@Testpublic void client(){try {SocketChannel sc = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8080));//设置为非阻塞模式sc.configureBlocking(false);FileInputStream fis = new FileInputStream(new File("1.jpg"));FileChannel inChannel = fis.getChannel();ByteBuffer dst = ByteBuffer.allocate(1024);while(inChannel.read(dst) != -1){dst.flip();sc.write(dst);dst.clear();}inChannel.close();fis.close();sc.close();} catch (IOException e) {e.printStackTrace();}}@Testpublic void test2(){try {SocketChannel sc = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8080));sc.configureBlocking(false);ByteBuffer src = ByteBuffer.allocate(1024);src.put(new Date().toString().getBytes());src.flip();sc.write(src);src.clear();sc.close();} catch (IOException e) {e.printStackTrace();}}@Testpublic void server(){try {ServerSocketChannel ssc = ServerSocketChannel.open();//1//设置为非阻塞模式ssc.configureBlocking(false);//2ssc.bind(new InetSocketAddress(8080));//3ByteBuffer buf = ByteBuffer.allocate(1024);FileOutputStream fos = new FileOutputStream(new File("2.jpg"));FileChannel outChannel = fos.getChannel();SocketChannel sc = null;//用open()获取选择器Selector selector = Selector.open();//4/**注册通道到选择器上,指定监控状态(SelectionKey选择键) * SelectionKey.OP_ACCEPT---接收事件 * SelectionKey.OP_CONNECT---连接事件 * SelectionKey.OP_READ---读事件 * SelectionKey.OP_WRITE---写事件 * 若监听事件不止一个时,可以使用"位或"操作符连接;int ops = SelectionKey.OP_ACCEPT | SelectionKey.OP_READ; */ssc.register(selector, SelectionKey.OP_ACCEPT);//5//轮询获取选择器上准备就序的监听事件while(selector.select() > 0){//selector.select()>0说明至少有一个通道准备就序Set<SelectionKey> keys = selector.selectedKeys();Iterator<SelectionKey> its = keys.iterator();while(its.hasNext()){SelectionKey selectionKey = its.next();//遍历所有准备就序的监听事件SelectionKey,并进行判断if(selectionKey.isAcceptable()){//可以启动单独的线程来处理//若接收就序就打开服务端连接sc = ssc.accept();sc.configureBlocking(false);sc.register(selector, SelectionKey.OP_READ);//...后序读操作}else if(selectionKey.isConnectable()){//可以启动单独的线程来处理}else if(selectionKey.isReadable()){//可以启动单独的线程来处理sc = (SocketChannel) selectionKey.channel();//sc.configureBlocking(false);//sc.register(selector, SelectionKey.OP_READ);int len = -1;while((len = sc.read(buf))!= -1){buf.flip();outChannel.write(buf);buf.clear();}}else if(selectionKey.isWritable()){//可以启动单独的线程来处理}}//selectionKey用完后取消掉its.remove();}outChannel.close();fos.close();sc.close();ssc.close();} catch (IOException e) {e.printStackTrace();}}}
阅读全文