先来看些nio基础的类库关系图 用pd大致画了下
相关的图片
上面是一些理论的关系图 下面是一些测试代码 相关的代码 都加了必要的注释
文件通道 FileChannel
package test; import java.io.IOException; import java.io.RandomAccessFile; import java.net.URISyntaxException; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousFileChannel; import java.nio.channels.CompletionHandler; import java.nio.channels.FileChannel; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import org.junit.After; import org.junit.Before; import org.junit.Test; /** * 文件通道测试类 * FileChannel文件通道只能使用阻塞模式 * AsynchronousFileChannel 异步 可以使用异步模式 * A FileChannel cannot be set into non-blocking mode. It always runs in blocking mode * @author u1 * */ public class BasicFileChannel { RandomAccessFile randomAccessFile; FileChannel channel; ByteBuffer buffer; AsynchronousFileChannel fileChannel; @Before public void before() throws IOException{ randomAccessFile=new RandomAccessFile(ClassLoader.getSystemResource("selector.txt").getFile(), "rw"); channel=randomAccessFile.getChannel(); //强制刷新 channel.force(true); buffer=ByteBuffer.allocate(102400); String aaa=buffer.toString(); System.out.println(aaa); } @After public void after() throws IOException{ randomAccessFile.close(); channel.close(); } /** * //1、读取数据Buffer //2、转换模式 //3、读取Buffer //4、清除Buffers * @throws IOException */ @Test public void readTest() throws IOException{ System.out.println(read()); } private String read() throws IOException { StringBuilder builder=new StringBuilder(); int readByte=channel.read(buffer); while(readByte!=-1){ //1、读取数据Buffer //2、转换模式 buffer.flip(); //3、读取Buffer byte[] datas=new byte[buffer.limit()]; buffer.get(datas); //System.out.println(new String(datas)); builder.append(new String(datas)); //4、清除Buffer buffer.clear(); readByte=channel.read(buffer); } String aa=builder.toString(); return aa; } /** * 将读出的文件内容回写到文件中 * 从文件的开始地方写入 * @throws IOException */ @Test public void writeTest() { try { //获取原有字符串 String originString=read(); //写入到buffer buffer.put(originString.getBytes()); //转换模式 buffer.flip(); //将buffer中的数据写入到文件中 channel.position(0); System.out.println("size:"+channel.size()+"\t"+"position:"+channel.position()); @SuppressWarnings("resource") RandomAccessFile randomAccessFile2=new RandomAccessFile("/home/lhy/data/aaaa.txt", "rw"); FileChannel channel2=randomAccessFile2.getChannel(); while(buffer.hasRemaining()) { channel2.write(buffer); System.out.println("0000000000000000"); } } catch (Exception e) { e.printStackTrace(); } System.out.println("11111111111111111111111"); } //@Test public void writeAsyncTest() throws IOException, URISyntaxException{ //获取原有字符串 String originString=read(); originString+=System.currentTimeMillis(); //写入到buffer buffer.put(originString.getBytes()); //转换模式 buffer.flip(); //Path file=Paths.get(ClassLoader.getSystemResource("selector1.txt").toURI()); Path file=Paths.get("/home/lhy/data/aaaa.txt"); fileChannel=AsynchronousFileChannel.open(file, StandardOpenOption.WRITE); fileChannel.force(true); //fileChannel.write(buffer, 10); fileChannel.write(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() { @Override public void completed(Integer result, ByteBuffer attachment) { // TODO Auto-generated method stub System.out.println("写完文件后操作,不阻塞,已经写了"+result); close(); } @Override public void failed(Throwable exc, ByteBuffer attachment) { // TODO Auto-generated method stub System.out.println("写失败"); exc.printStackTrace(); } }); System.out.println("000000000000000000000000000000000000000000000000000000"); } public void close(){ try { fileChannel.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }多路复用器 Selector
服务端
[java] view plain copy 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] view plain copy package com.undergrowth; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.net.Socket; /** * 连接服务ServerSocket * @author u1 * */ public class BasicSocketChannel { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // TODO Auto-generated method stub //用于客户端的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] view plain copy package com.undergrowth; import java.nio.file.Path; import java.nio.file.Paths; import org.junit.Test; /** * 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. * * @author u1 * */ public class BasicPath { /** * 测试绝对路径 */ @Test public void testAbsolute() { Path path=Paths.get("E:\\book", "JAVA_API_1.7中文.chm"); System.out.println(path.toString()); } /** * 测试相对路径 * .---->当前路径 * ..---->父路径 */ @Test public void testRelative(){ Path path=Paths.get("."); System.out.println(path.toAbsolutePath()); path=Paths.get(".."); System.out.println(path.toAbsolutePath()); } /** * 格式化Path路径 * 去除.和.. */ @Test public void testNormalize(){ Path path=Paths.get("E:\\book\\weblogic\\.\\51CTO下载-Oracle WebLogic Server开发权威指南.part1.rar"); System.out.println(path.toAbsolutePath()); System.out.println(path.normalize().toAbsolutePath()); path=Paths.get("E:\\book\\..\\"); System.out.println(path.toAbsolutePath()); System.out.println(path.normalize().toAbsolutePath()); } }管道 Pipe
[java] view plain copy package com.undergrowth; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.Pipe; import org.junit.Before; import org.junit.Test; /** * 管道操作 * * 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 * * @author u1 * */ public class BasicPipe { Pipe pipe; Pipe.SinkChannel writePipe; Pipe.SourceChannel readPipe; ByteBuffer buffer; @Before public void before() throws IOException{ pipe=Pipe.open(); writePipe=pipe.sink(); readPipe=pipe.source(); buffer=ByteBuffer.allocate(1024); } @Test 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] view plain copy package com.undergrowth; import static org.junit.Assert.*; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.FileVisitor; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; import java.nio.file.attribute.BasicFileAttributes; import org.junit.Test; /** * The Java NIO Files class (java.nio.file.Files) provides several methods for * manipulating files in the file system. * 文件操作类 * 新建两个文件夹 再将文件复制到两文件夹中 然后进行遍历文件树 遍历完成后 删除文件夹及文件 * @author u1 * */ public class BasicFiles { @Test 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 * @throws IOException */ private void walkFile(Path path) throws IOException { // TODO Auto-generated method stub 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; } @Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { // TODO Auto-generated method stub //遍历完目录后删除 System.out.println("遍历完目录后删除"+dir.toAbsolutePath()); Files.delete(dir); return FileVisitResult.CONTINUE; } }); } /** * 复制文件 * @param path * @throws IOException */ private void copyFiles(Path path) throws IOException { // TODO Auto-generated method stub 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"); Files.copy(pathSource, path,StandardCopyOption.REPLACE_EXISTING); } /** * 创建文件夹 * @param path * @throws IOException */ private void createDir(Path path) throws IOException { // TODO Auto-generated method stub if(!Files.exists(path, new LinkOption[]{LinkOption.NOFOLLOW_LINKS})) Files.createDirectories(path); path=Paths.get(path.toString(), "test1"); if(!Files.exists(path, new LinkOption[]{LinkOption.NOFOLLOW_LINKS})) Files.createDirectories(path); path=Paths.get(path.toString(), "..\\test2"); if(!Files.exists(path, new LinkOption[]{LinkOption.NOFOLLOW_LINKS})) Files.createDirectories(path); } } 相关资源:python入门教程(PDF版)