Java nio

Java提供了NIO来提高在文件上的访问速度,主要由缓冲器buffer和与缓冲器打交道的FileChannel 道之所以速度快于旧的IO库,是它的结构更接近于os执行IO的方式

Buffer 的子类有:ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer 和 shortBuffer.


缓冲器的4个细节  ps:引用我在另一端博文中看到的介绍 我觉得会比本人所写的更容易理解

  • 容量(Capacity):缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能被改变。
  • 上界(Limit):缓冲区的第一个不能被读或写的元素。缓冲创建时,limit 的值等于 capacity 的值。假设 capacity = 1024,我们在程序中设置了 limit = 512,说明,Buffer 的容量为 1024,但是从 512 之后既不能读也不能写,因此可以理解成,Buffer 的实际可用大小为 512。
  • 位置(Position):下一个要被读或写的元素的索引。位置会自动由相应的 get() 和 put() 函数更新。 这里需要注意的是positon的位置是从0开始的。
  • 标记(Mark):一个备忘位置。标记在设定前是未定义的(undefined)。使用场景是,假设缓冲区中有 10 个元素,position 目前的位置为 2(也就是如果get的话是第三个元素),现在只想发送 6 - 10 之间的缓冲数据,此时我们可以 buffer.mark(buffer.position()),即把当前的 position 记入 mark 中,然后 buffer.postion(6),此时发送给 channel 的数据就是 6 - 10 的数据。发送完后,我们可以调用 buffer.reset() 使得 position = mark,因此这里的 mark 只是用于临时记录一下位置用的。
请切记,在使用 Buffer 时,我们实际操作的就是 这四个属性的值。 我们发现,Buffer 类并没有包括 get() 或 put() 函数。但是,每一个Buffer 的子类都有这两个函数,但它们所采用的参数类型,以及它们返回的数据类型,对每个子类来说都是唯一的,所以它们不能在顶层 Buffer 类中被抽象地声明。它们的定义必须被特定类型的子类所遵从。 


面是我自己对NIO中的 FileChannel  和 ByteBuffer 愚见:

                

ByteBuffer是一个唯一与通道交互的缓冲器 下面是它的常用发法:

  ByteBuffer buffer =ByteByifer.allocate(SIZE);  //SIZE是分配ByteBuffer的数量 它可以是一个static变量 在分配之后不可以在变 所以分配多少数目尤为重要。

   buffer.wrap("  xxxxxxx".getBytes()); //只能用于接收byte类型的数据, 所以需要将它转化为byte字节数组 用getBytes().   当然也可以使用put方法直接进行填充。

                   buffer.flip() 用于反转通道 .此外他还有另一种含义 将在下面介绍.


尽管ByteBuffer只能保存字节类型的数据,但是它具有可以从其所容纳的的字节中产生出各种不同基本类型值的方法。记住是基本类型。向基本类型插入数据的最简单方法就是使用asCharBuffer() ,  asShortBuffer()等等 然后使用put() 方法

                    buffer.asShortBuffer().put((short) 1234) //在使用shortBuffer put方法时 需要强制转换成short 而其他的所有基本类型都不需要

                                        


  FileChannel 是一个与缓冲器交互的通道 它由三个类所产生分别为 FileInputStream FileOutputStream 和 可读可写的RandomAccessFile 因为这三个类是字节操作流所以不能用字符操作流Reader和Witer产生通道. 下面是对FileChannel的常用方法做解释:

FileChannel  channel = new RandomAccessFile("文件名","rw") .getChannel;  //对FileChannel 实例化 getChannel用于关联唯一文件通道

                         channel.wrier() //用于写入数据  他的参数必须是buffer 类型

                          channel.read() //读取数据   这里需要注意 每次读取数据后需要反转 所以他的后面必须接上 buffer.filp()

                          channel.position()  //设置读写位置


下面是对上文所写出的java代码 在d盘data.txt文件上读写数据:   

  import java.io.*;

import java.util.*;
import java.nio.*;
import java.nio.channels.*;
public class Channel {


private static final int BSIZE = 1024;
public static void main(String[] args)throws IOException {
ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
buffer.asShortBuffer().put((short)123);
 
       
   FileChannel channel = new FileOutputStream("d://data.txt").getChannel();//getChannel与D盘data关联  
        channel.write(ByteBuffer.wrap("data_name".getBytes()));   
        channel.close(); 
  
        channel = new FileInputStream("d://data.txt").getChannel();  
        channel.read(buffer);  
        buffer.flip();// 反转此通道  
        
            
        channel = new RandomAccessFile("d://data.txt", "rw").getChannel();//可读可写模式关联  
        channel.position(channel.size());// 移动到文件结尾  
        channel.write(ByteBuffer.wrap(" data_name".getBytes()));  
        channel.close();  
  
       
        while (buffer.hasRemaining()) {  
       System.out.println((char) buffer.get());  
        }


}


}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值