java newio_Java文件与io——NewIO

为啥要使用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

dcc7f5308ff73c21eb98897e5b84de6b.png

public classNIIODemo {/***@paramargs*/

public static voidmain(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

System.out.println(buf.get(i));

}

}

}

0809a6eb39e0116cf90e7248dadf3965.png

通道:Channel

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

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

/*** 文件的读写操作:1.内存映射方式(最快) 2.NIO的文件通道读写(第二块) 3.传统的IO读写(最慢)

*@authorAdministrator

**/

public classFileCopyDemo {/***@paramargs*/

public static voidmain(String[] args) {//TODO Auto-generated method stub//copy(new File("c:\\aaa.txt"),new File("c:\\aaa\\aaa.txt"));

RandomAccessFileDemo();

}public static voidcopy(File src,File dest){try{

FileInputStream in=newFileInputStream(src);

FileOutputStream out=newFileOutputStream(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 voidRandomAccessFileDemo(){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

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();

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值