为啥要使用NIO?

NIO的创建目的是为了让JAVA程序员可以实现高速I/O而无需编写自定义的本机代码。NIO将最耗时的I/O操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度

流与快的比较

原来的I/O库(在java.io.*中)与NIO最重要的区别是数据打包和传输的方式,原来的I/O以流的方式处理数据,而NIO以快的方式处理数据。

面向流的I/O系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。不利的一面是,面向流的I/O通常相当慢。

一个面向快的I/O系统以快的形式处理数据。每一个操作都在一步中产生或消费一个数据块。按快处理数据比按(流式的)字节处理数据要快的多,但是面向快的I/O缺少一些面向流的I/O所具有的优雅性和简单性。

缓冲区

在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读取到缓冲区中的,在写入数据时,它是写入到缓冲区中的。任何时候访问NIO中的数据,都是将它放到缓冲区中

缓冲区实质上一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不仅仅是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。

缓冲区类型

最常用的缓冲区类型是ByteBuffer。一个ByteBuffer可以在其底层字节数组上进行get/set操作(即字节的获取和设置)。ByteBuffer不是NIO中唯一的缓冲区类型。事实上,对于每一种基本java类型都有一种缓冲区类型:

ByteBuffer   CharBuffer  ShortBuffer  IntBuffer  LongBuffer  FloatBuffer  DoubleBuffer

缓冲区内部细节:

状态变量

可以用三个值指定缓冲区在任意时刻的状态:

position                             limit         capacity

public class NIIODemo {

    /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("----------");
ByteBuffer buf=ByteBuffer.allocate(10);
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
System.out.println("----------");
buf.put((byte) 10);
byte[] bs={20,30,40};
buf.put(bs);
ByteBuffer buf1=ByteBuffer.allocate(10);
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
System.out.println("----------");
buf.flip();//反转,将position回到初始位置,limit等于position的值
ByteBuffer buf2=ByteBuffer.allocate(10);
System.out.println("position="+buf.position());
System.out.println("limit="+buf.limit());
System.out.println("capacity="+buf.capacity());
System.out.println("----------"); //取值
//返回当前位置与限制之间的元素
for(int i=0;i<buf.remaining();i++){
System.out.println(buf.get(i));
}
} }

通道:Channel

Channel是一个对象,可以通过它读取和写入数据。拿NIO与原来的I/O做个比较,通道就像是流。

正如前面提到的,所有数据都通过Buffer对象来处理。永远不会将字节直接写入通道中,相反,您是将数据写入包含一个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。

/**
* 文件的读写操作:1.内存映射方式(最快) 2.NIO的文件通道读写(第二块) 3.传统的IO读写(最慢)
* @author Administrator
*
*/
public class FileCopyDemo { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//copy(new File("c:\\aaa.txt"),new File("c:\\aaa\\aaa.txt"));
RandomAccessFileDemo();
} public static void copy(File src,File dest){
try {
FileInputStream in=new FileInputStream(src);
FileOutputStream out=new FileOutputStream(dest);
FileChannel fcin=in.getChannel();//获取文件通道
FileChannel fcout=out.getChannel(); ByteBuffer buf=ByteBuffer.allocate((int)src.length());
fcin.read(buf);
buf.flip();
fcout.write(buf); fcin.close();
fcout.close();
in.close();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } public static void RandomAccessFileDemo(){
try {
RandomAccessFile in=new RandomAccessFile(new File("c:\\aaa.txt"),"r");
RandomAccessFile out=new RandomAccessFile(new File("c:\\aaa\\aaa.txt"),"rw"); FileChannel inChannel=in.getChannel();
FileChannel outChannel=out.getChannel();
long size=inChannel.size();
//映射内存
MappedByteBuffer inbuf=inChannel.map(MapMode.READ_ONLY, 0, size);
MappedByteBuffer outbuf=outChannel.map(MapMode.READ_WRITE, 0, size);
//buf.flip();
for(int i=0;i<size;i++){
byte b=inbuf.get(i);
outbuf.put(i,b);
} inChannel.close();
outChannel.close();
in.close();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

Java文件与io——NewIO的更多相关文章

  1. Java文件与io——打印流和对象流

    打印流的主要功能是用于输出,在整个IO包中打印流分为两种类型: 字节打印流:PrintStream 字符打印流:PrintWriter 打印流可以很方便的进行输出 public class Print ...

  2. Java文件与io——RandomAccessFile

    RandomAccessFile是IO包的类,从Object直接继承而来.只可以对文件进行操作,可以对文件进行读取和写入.RandomAccessFile有强大的文件读写功能,其内部是大型byte[] ...

  3. Java文件与io——复制文件和转换流

    字节流与字符流的区别 在所有的流操作里,字节永远是最基础的.任何基于字节的操作都是正确的.无论是文本文件还是二进制的文件. 如果确认流里面只有可打印的字符,包括英文的和各种国家的文字,也包括中文,那么 ...

  4. Java文件与io——常见字符编码

    在计算机世界里,任何的文字都是以指定的编码方式存在的. 常见编码有:ISO8859-1.GBK/GB2312.unicode.UTF ISO8859-1:编码属于单字节编码,最多只能表示0-255的字 ...

  5. Java文件与io——装饰者模式

    意图: 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式相比于生成子类更为灵活.该模式以对客户端透明的方式扩展对象的功能. 适用环境 在不影响其他对象的情况下,以动态.透明的 ...

  6. Java文件与io——字节数组流数据流字符串流

    字节数组流 ByteArrayInputStream:包含一个内部缓冲区,该缓冲区包含从流中读取的字节.内部计数器跟踪read方法要提供的下一个字节.关闭ByteArrayInputStream无效. ...

  7. Java文件与io——缓冲流

    对文件或其它目标频繁的读写操作,效率低,性能差. 使用缓冲流的好处,能够更高效的读写信息,原理是将数据先缓冲起来,然后一起写入或者读取出来. BufferedInputStream:为另一个输入流添加 ...

  8. Java文件与io——字符流

    Writer写入字符流的抽象类.对文件的操作使用:FileWriter类完成 Reader读取字符的抽象类. public class CharDemo { /** * @param args */ ...

  9. Java文件与io——字节流

    FileOutputStream用于写入诸如图像数据之类的原始字节的流 字节输出流:OutputStream 此抽象类表示输出字节流的所有类的超类.(写) 字节输入流:InputStream(读) p ...

随机推荐

  1. docker数据卷(volume)

    1.什么是数据卷volume https://blog.csdn.net/dream_broken/article/details/52314993 为了了解什么是Docker Volume,首先我们 ...

  2. java.util Properties使用记录

    转:http://www.2cto.com/px/201006/47834.html 在java.util 包下面有一个类 Properties,该类主要用于读取以项目的配置文件(以.properti ...

  3. python 链表

    在C/C++中,通常采用“指针+结构体”来实现链表:而在Python中,则可以采用“引用+类”来实现链表. 节点类: class Node: def __init__(self, data): sel ...

  4. TS学习之接口

    TypeScript的核心原则之一是对值所具有的结构进行类型检查.接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约. interface testType { name: string; ...

  5. Tomcat 服务器详解

    工具/原料 1.JDK:版本为jdk-7-windows-i586.exe  下载地址   http://www.oracle.com/technetwork/java/javase/download ...

  6. ADO.NET 对象

    (一)OleDbConnection 使用COM组件链接 (二)ADO.NET 对对数据库访问做了优化: 1.SqlConnection 用于建立和Sql Server服务器连接的类,表示打开数据库 ...

  7. WEB 项目中的全局异常处理

    在web 项目中,遇到异常一般有两种处理方式:try.....catch....:throw 通常情况下我们用try.....catch.... 对异常进行捕捉处理,可是在实际项目中随时的进行异常捕捉 ...

  8. mongodb 查询数据

    MongoDB概念解析: 等同于SQL的数据库表:collectiondocument:等同于SQL的数据记录行field:等同于SQL的数据字段表连接,MongoDB不支持主键,MongoDB自动将 ...

  9. SpringSecurity02 表单登录、SpringSecurity配置类

    1 功能需求 springSecuriy默认的登录窗口是一个弹出窗口,而且会默认对所有的请求都进行拦截:要求更改登录页面(使用表单登录).排除掉一些请求的拦截 2 编写一个springSecurity ...

  10. unreal3对象管理模块分析

    凡是稍微大一点的引擎框架,必然都要自己搞一套对象管理机制,如mfc.qt.glib等等,unreal自然也不例外. 究其原因,还是c++这种静态语言天生的不足,缺乏运行时类型操作功能,对于复杂庞大的逻 ...