Please Call Me NIO
与其他语言相比,Java的IO功能显得异常复杂,各种流操作,通过程序员多次封装才可以达到操作文件的目的。自从jdk1.4之后,java提供了一个新的api完成IO操作,人称New IO(NIO),使用java nio包来进行IO操作,相比原先的API相比要方便多了(每次用老的api写IO操作,心中就会有千万的草泥马飘过)。Jdk1.7发布后,java nio又有了新的改进,人称NIO.2。终于java的IO操作可以和其他语言接轨了T^T。

下面就来了解下java的NIO包(注意了啊~这里我使用的jdk版本是1.7)
探索Path与Files
在java 7 中文件路径和对文件的操作被很清晰地用两个类分开了,路径全部使用Path来处理,而文件的操作则通过Files类来操作。
Path的创建非常简单,通过Paths.get()方法就可以获得了。
Path path=Paths.get("F:\\javawork\\eclipsework");
System.out.println(path.toAbsolutePath());
System.out.println(path.getFileName());
System.out.println(path.getRoot());
System.out.println(path.getParent());
System.out.println(path.getNameCount());
通过这个path对象,就可以获得很多和路径有关的信息了。
为了兼容java 6 ,File类中特别添加了一个toPath() 方法帮助File类获取Ptah对象,于此同时,Path也拥有一个toFile()方法,方便两个类相互转换。
有了Path的帮助,接下来就是处理文件的操作了。我们在获取的了相应的路径之后,现在就需要Files类来操作文件了。
之前提到路径的处理和文件的处理被分的很清楚,那么文件的相关信息,就只有由Files类来完成了。
Path path=Paths.get("F:\\javawork\\eclipsework\\jdk7Test\\src\\pro\\app\\hello2.txt");
System.out.println(Files.getLastModifiedTime(path));
System.out.println(Files.size(path));
System.out.println(Files.isSymbolicLink(path));
System.out.println(Files.isDirectory(path));
System.out.println(Files.readAttributes(path,"*"));
使用Files才完成文件的创建、删除、复制和移动操作也是非常方便。
//path和target均是Path类的对象
Files.createFile(path); //创建文件
Files.delete(path); //删除文件
Files.copy(path, target); //复制文件
Files.move(path, target); //移动文件
同时copy()和move()方法均有第三个参数(通过import static java.nio.file.StandardCopyOption.*;获得常量)。
REPLACE_EXISTING 替换已经存在的文件
COPY_ATTRIBUTES 复制文件属性
ATOMIC_MOVE 确保两边操作均成功,否则回滚
文件的读取与写入
想到要用java对文件操作就很痛苦,有木有~流过来,输出入~泥煤哒!!jdk1.7已经开始解放大家的痛苦了。(当然java原先的IO操作让程序员有更高的自由度,可以非常容易滴处理IO的细节,但有时候,咱真的没有那个需求啊~)。
Path path=Paths.get("test.txt");
List<String> lines=Files.readAllLines(path,StandardCharsets.UTF_8); for(String line:lines){
System.out.println(line);
}
很简单有木有,如果想通过byte类型获取数据可以这么操作。
byte[] bytes=Files.readAllBytes(path);
for(byte b:bytes){
String temp=new String(new byte[]{b});
System.out.print(temp);
}
读了文件之后,现在就要开始写入文件了,这里使用Files类的write方法~
Path path=Paths.get("F:\\javawork\\eclipsework\\jdk7Test\\src\\pro\\app\\hello2.txt");
String temp="hello world~";
Files.write(path,temp.getBytes(),StandardOpenOption.APPEND);
不要太轻松啊~啊哈哈哈哈哈。
异步IO
NIO给我们带来最大的惊喜就是异步的IO操作了,相比传统的IO方式,NIO通过异步操作极大地提升了IO的通信。异步IO允许程序在结束IO操作之前,处理其他的事情。这样就可以充分地利用CPU了。想象一下在完成一个100G的文件操作时,如果是老版本的api,我们在完成IO操作之前,除了等待还是无奈的等待~~~
新的异步IO主要有两种形式,将来式和回调式(有种学英语的感觉orz)。我们先来看看将来式。
Path path=Paths.get("F:\\javawork\\eclipsework\\jdk7Test\\src\\pro\\app\\hello2.txt");
//异步打开文件
try(AsynchronousFileChannel channel=AsynchronousFileChannel.open(path)){
ByteBuffer buffer=ByteBuffer.allocate(100_000);
Future<Integer> result=channel.read(buffer, 0);
//使用isDone()判断result是否结束
while(!result.isDone()){
//do something else
}
buffer.flip();
while(buffer.hasRemaining()){
System.out.print((char) buffer.get());
}
//clear()方法会清空整个缓冲区
buffer.clear();
Integer byteRead=result.get();
System.out.println(byteRead);
}catch(IOException | ExecutionException | InterruptedException e){
System.out.println(e.getMessage());
}
在完成读取之前,我们可以在 while(!result.isDone())中完成其他的事儿~
这里可以复习下nio的一些概念,Java NIO 是面向缓存Buffer的IO操作方式。
Buffer的本质是一块可以读写数据的内存,NIO将其封装成一个对象。可以将它视作一个集装箱,咱把货物装好了,打包就可以从通道送出去了。
而Channel是IO操作中的通道,我们通过通道获得数据,输出数据,好比是马路,我们想要搬运货物都得通过这个通道。
前面提到Buffer是一块可以读写的内存,一般我们使用Buffer有这么几个步骤:
1、 声明Buffer大小
2、 写入数据到buffer
3、 调用filp()方法
4、 从Buffer中读取数据,放到相应的位置
5、 调用clear()或者compact()方法清理Buffer的内存空间
Buffer有这么几个类型:ByteBuffer、MappedByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer
很惊讶有木有!这就是java的基本类型加了个Buffer啊,想要什么类型的数据,咱就用什么类型的Buffer,每次使用之前就通过allocate()方法来给Buffer分配大小。
再有,之前的jdk版本(1.7之前的版本)写IO操作最怕忘记写close()方法了,在新的api中try语句之后可以接上一个括号,在括号中声明需要保护的资源,然后交给java来关闭这个资源。
接下来再看看回调式,比起将来式的写法,这种更加自然一些。有点像ajax的写法。
Path path=Paths.get("test.txt");
try(AsynchronousFileChannel channel=AsynchronousFileChannel.open(path);){
ByteBuffer buffer=ByteBuffer.allocate(100_000);
channel.read(buffer,0,buffer,new CompletionHandler<Integer,ByteBuffer>(){
@Override
public void completed(Integer result,ByteBuffer attachment){
System.out.println(result);
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
System.out.println(exc.getMessage());
}
});
}catch(IOException e){
System.out.println(e.getMessage());
}
主线程派出一个侦查员CompletionHandler,来观察独立线程的IO操作,如果IO操作成功则调用CompletionHandler中的completed()中的方法,如果失败就调用failed方法,采取行动挽救损失。
总结
Path类与Files类
文件的写入与读取
IO的异步
Please Call Me NIO的更多相关文章
- 源码分析netty服务器创建过程vs java nio服务器创建
1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...
- BIO\NIO\AIO记录
IO操作可以分为3类:同步阻塞(BIO).同步非阻塞(NIO).异步(AIO). 同步阻塞(BIO):在此种方式下,用户线程发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后, ...
- 支撑Java NIO 与 NodeJS的底层技术
支撑Java NIO 与 NodeJS的底层技术 众所周知在近几个版本的Java中增加了一些对Java NIO.NIO2的支持,与此同时NodeJS技术栈中最为人称道的优势之一就是其高性能IO,那么我 ...
- Java I/O and NIO [reproduced]
Java I/O and NIO.2---Five ways to maximize Java NIO and NIO.2---Build more responsive Java applicati ...
- JAVA NIO学习笔记1 - 架构简介
最近项目中遇到不少NIO相关知识,之前对这块接触得较少,算是我的一个盲区,打算花点时间学习,简单做一点个人学习总结. 简介 NIO(New IO)是JDK1.4以后推出的全新IO API,相比传统IO ...
- Java NIO概述
Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然 Java NIO 中除此之外还有很多类和组件,但在我看来,Channel,Buffer 和 Se ...
- JAVA NIO Socket通道
DatagramChannel和SocketChannel都实现定义读写功能,ServerSocketChannel不实现,只负责监听传入的连接,并建立新的SocketChannel,本身不传输数 ...
- JAVA NIO FileChannel 内存映射文件
文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...
- java nio系列文章
java nio系列教程 基于NIO的Client/Server程序实践 (推荐) java nio与并发编程相关电子书籍 (访问密码 48dd) 理解NIO nio学习记录 图解ByteBuff ...
- (转)NIO与AIO,同步/异步,阻塞/非阻塞
原文地址: http://www.cnblogs.com/enjoy-ourselves/p/3793771.html 1.flip(),compact(),与clear()的使用 flip()内部实 ...
随机推荐
- 使用GizwitsOpenAPI,快速开发轻应用
导读:使用机智云提供的Open API(Http / WebSocket),可以快速开发网页或微信应用等基于html的轻应用,用于管理和控制智能设备.机智云 Open API 主要帮助开发者通过 HT ...
- Tween Animation---Scale渐变尺寸缩放动画
博主都是自己把代码测试过了才给大家分享的 在res/创建一个anim文件夹用来保存动画属性的xml 新建一个scale.xml <?xml version="1.0" enc ...
- DFS序+线段树 hihoCoder 1381 Little Y's Tree(树的连通块的直径和)
题目链接 #1381 : Little Y's Tree 时间限制:24000ms 单点时限:4000ms 内存限制:512MB 描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每 ...
- 缺少.lib文件导致的Link2019 解决方案汇总
环境Vs2015, Win10 添加lib的方法在末尾 下面的错误都是我在写Direct3D程序中遇到的, 记下来方便查找 4.ws2_32.lib 3. version.lib _GetFil ...
- iOS分析UI利器——Reveal简单使用
一,简单使用 * 在xcode中打开你的项目(project); * 打开reveal 和选中 Help → Show Reveal Library in Finder * 把Reveal.frame ...
- 【BO】SAP BO相关问题汇总贴
本文将以往写过的关于SAP BO相关问题的帖子汇总了一下,方便寻找 #1 为WEBI报表添加自定义字体font #2 WEBI文件打开时提示Illegal access错误 #3 安装BO服务器时,o ...
- 2.1 -1.0 Xcode(发布时间、使用、快捷键、插件相关)
本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” 1.0 Xcode 发布时间 版本 iOS 版本 手机 日期 特殊介绍 Xcode 3.1 ...
- CODEVS 天梯 代码记录
所有水题均被折叠 Lv.1 青铜 1201 #include<iostream> #include<cstring> #include<algorithm> #in ...
- swift-闭包(代码块)
语法 通用的语法 {(parameters) -> return type in statements } e.g let studname = { println("Welcome ...
- lucene和es总结
一.首先介绍lucene涉及到的排序过程 1.1.如何自定义排序对象 你可以自定义collector对象: 亦可以自定义comparator对象: 可以自定义scoredoc对象,决定如何处理结果集合 ...