Java7 NIO2

来源:互联网 发布:mit 为什么使用python 编辑:程序博客网 时间:2024/05/19 17:05
NIO2的关键基础类:
     Path:该类中的方法可以用来获取路径信息,访问该路径中的各元素,将路径转换为其他形式,或提取路径中的一部分。有的方法还可以匹配路径字串以及移除路径中的冗余项
     Paths:工具类,提供一个返回一个路径的的辅助方法,比如get(String first,String ... more)和get(URI uri)
     FileSystem:与文件系统交互的类,无论是默认的文件系统还是通过其URI获取的可选文件系统
     FileSystems:工具类,提供各种方法,比如其中用于返回默认文件系统的FileSystems.getDefault()

在NIO2中path或paths的各种方法抛出的受检异常只有IOException

1.创建Path
     创建Path方法:
          a/Paths.get(String path)
          b/FileSystems.getDefault().getPath(String path)
     两者是等价的
2.从path中获取信息
     path.getFileName--获取当前文件名
     path.getNameCount--获取当前文件数量
     path.getParent--获取当前路径的父路径
     path.getRoot--获取根路径
     path.subpath(beginIndex,endIndex)--获取根路径与当前路径之间的子路径
     path.toAbsolutePath--把相对路径转换为绝对路径
3.移除冗余项
     normalize()方法和toRealPath()可以去除冗余项,得到真正的path
4.转换Path
     resolve():合并路径
     relativize():计算两个路径之间的路径                
5.Java File类与NIO2 Path
     File类的toPath()方法可以将File类转化为NIO2的Path
     Path类的toFile()方法可以将Path类转化为File
6.在目录中查找文件
     示例代码如下:
Path dir=Paths.get("F:/Tmp/Learn");try(DirectoryStream<Path> stream=Files.newDirectoryStream(dir,"*.txt")){for(Path entry:stream){System.out.println(entry.getFileName());}}catch(IOException e){               System.out.println(e.getMessage());}
7.遍历目录树
     示例代码如下:
Path dir=Paths.get("F:/Tmp");Files.walkFileTree(dir,new FindJavaVisitor());private static class FindJavaVisitor{@overridepublic FileVisitResult visitFile(Path File,BasicFileAttributes attrs){if(file.toString().endsWith(".txt"){System.out.println(file.getFileName());}return FileVisitResult.CONTINUE;}
}
8.创建和删除文件
     创建文件:Files.createFile(Path path);
          还可以在创建文件时加入attr属性,指定只读、可写、可执行
     删除文件:Files.delete(Path path);
9.文件的移动和复制
     Files.copy(Path source,Path target);    
     复制属性包括:REPLACE_EXISTING(覆盖替换),COPY_ATTRIBUTES(复制文件属性),ATOMIC_MOVE(确保两边操作都成功,否则回滚)
     移动方法名为move,其他与复制同
10.文件属性
     为了支持文件系统特定的文件属性,java7允许文件系统提供者实现FileAttributeView和BasicFileAttributes接口
     Files.readAttributes(Path path,String pattern);--获取当前路径下文件属性
11.快速读写文件
     示例代码如下
     Read:
Path path=Paths.get("F:/Tmp");try(BufferedReaderbr=Files.newBufferedReader(path,StandardCharsets.UTF_8);){String line;while((line=br.readLine())!=null){//doSomething}}
     Write:
Path path=Paths.get("F:/Tmp");try(BufferedWriterbw=Files.newBufferedWriter(dir,StandardCharsets.UTF_8,StandardOpenOption.WRITE)){//doSomething}
读取全部字符串:
          List<String>lines=Files.readAllLines(dir,StandardCharsets.UTF_8);
     读取全部字节:
          byte[]bytes=Files.readAllBytes(dir);    
12.文件修改通知
     监测变化->检查shutdown标志->得到下一个key及其事件->检查是否为变化事件->重置检测key    
     示例代码如下:
try{WatchService watcher=FileSystems.getDefault().newWatchService();Path dir=Paths.get("F:/Tmp");WatchKey key=dir.register(watcher,ENTRY_MODIFY);while(!shutdown){key=watcher.take();for(WatchEvent<?>event:key.pollEvents()){if(event.kind()==ENTRY_MODIFY){//doSomething}}key.reset();}catch(IOException|InterruptedException e){System.out.println(e.getMessage());}
   其他可监测事件有:ENTRY_CREATE,ENTRY_DELETE和OVERFLOW
13.异步IO操作
     java7中有3个异步通道:
          AsynchronousFileChannel--用于文件IO
          AsynchronousSocketChannel--用于套接字IO
          AsynchronousServerSocketChannel--用于套接字接受异步连接
     使用新的IO api时主要有两种形式:将来式和回调式
          A.将来式    
          当希望由主线程发起IO操作并轮询等待结果时,一般用将来式异步处理
          通常会用Future的get()方法在异步IO操作完成时获取其结果。(主线程可以在读取数据的同时继续完成其他操作)
          示例代码如下:
try{Path path=Paths.get("F:/Tmp");AsynchronousFileChannel channel=AsynchronousSocketChannel.open(path);ByteBuffer buffer=ByteBuffer.allocate(100_000);//读取100000字节Future<Integer>result=channel.read(buffer,0);while(!result.isDone()){//doSomething else}Integer bytesRead=result.get();System.out.println("Bytes Read["+bytesRead+"]");}catch(IOException|ExecutionException|InterruptedException e){System.out.println(e.getMessage());}
AsynchronousFileChannel会关联线程池,它的任务是接收IO处理事件,并分发给处理通道中IO操作结果的结果处理器。跟通道中发起的IO操作关联的结果处理器确保是由线程池中的某个线程产生的。如果在创建AsynchronousSocketChannel时没有为其指定线程池(可能会和其他通道共享),默认线程池是由AsynchronousFileChannelGroup类定义的系统属性进行配置的。
     B.回调式
     在异步事件刚一成功或失败并需要马上采取行动时,一般会用回调式。
     示例代码如下:
try{Path path=Paths.get("F:/Tmp");AsynchronousFileChannel channel=AsynchronousFileChannel.open(path);ByteBuffer buffer=ByteBuffer.allocate(100_000);channel.read(buffer,0,buffer,new CompletionHandler<Integer,ByteBuffer>(){public void completed(Integer result,ByteBuffer attachment){System.out.println("Bytes read["+result+"]");}public void failed(Throwable exception,ByteBuffer attachment){System.out.println(exception.getMessage());}});}catch(IOException e){System.out.println(e.getMessage());}
14.Socket和channel的整合
     套接字:两个机器间通信的端点    
     NetworkChannel示例代码:(NetworkChannel的出现使多播操作成为可能)
SelectorProvider provider=SelectorProvider.provider();try{NetworkChannel socketChannel=provider.openSocketChannel();SocketAddress address=new InetSocketAddress(3080);socketChannel=socketChannel.bind(address);Set<SocketOption<?>>socketOptions=socketChannel.supportedOptions();System.out.println(socketOptions.toString());socketChannel.setOption(StandardSocketOptions.IP_TOS,3);Boolean keepAlive=socketChannel.getOption(StandardSocketOptions.SO_KEEPALIVE);//...}catch(IOException e){System.out.println(e.getMessage());}
 MulticastChannel:
          多播(组播)表示一对多的网络通讯,通常用来指代IP多播。其基本前提是将一个包发送到一个组播地址,然后网络对该包进行复制,分发给所有接收端(注册到组播地址中)。为了对NetworkChannel加入多播组,java7提供了一个新接口java.nio.channels.MulticastChannel及其默认实现类DatagramChannel,即可以轻松对多播组发送和接收数据
          示例代码如下:
          选择网络接口->打开dc->将通道设置为多播->加入多播组
try{NetworkInterface networkInterface=NetworkInterface.getByName("netl");DatagramChannel dc=DatagramChannel.open(StandardProtocolFamily.INET);dc.setOption(StandardSocketOptions.SO_REUSEADDR,true);dc.bind(new InetSocketAddress(8080));dc.setOption(StandardSocketOptions.IP_MULTICAST_IF,networkInterface);InetAddress group=InetAddress.getByName("180.90.4.12");MembershipKey key=dc.join(group,networkInterface);}catch(IOException e){System.out.println(e.getMessage());}










0 0
原创粉丝点击