`

j2se -----nio----buffer and channel

    博客分类:
  • J2SE
阅读更多
缓冲区 如:ByteBuffer其实是对基本数据类型的封装 byte[]而已啦,
CharBuffer,ShortBuffer,IntBuffer,
LongBuffer,FloatBuffer,DoubleBuffer
其实这些所谓的缓冲区就是给基本数据类型多加了几个变量而已
position(当前可以放的位置),limit(最后一个元素位置),capacity

1.
IntBuffer buf = IntBuffer.allocate(10);
int temp={5,7,9};
buf.put(3);
buf.put(temp);

buf.flip(); //重设缓冲区(翻动---position=0;limit=原本的position)
while(buf.hasRemaining()){
   int x = buf.get();
}

2. 创建子缓冲区
public class Test{
  public static void main(String[] args){
     IntBuffer buf = IntBuffer.allocate(10);
     IntBuffer sub = null;
     for(int i=0;i<10;i++){
        buf.put(2*i+1);
     }
     buf.position(2);       //主缓冲区指针设置在第三个元素
     buf.limit(6);           //主缓冲区limit为6
     sub = buf.slice();      //开辟子缓冲区,也就是他有一个引用指向了buf的部分区域
     //sub = buf.asReadOnlyBuffer(); //创建只读缓冲区
      for(int i=0;i<sub.capacity();i++){
         int temp = sub.get(i);
         sub.put(temp -1);      //这是在改变buf中的东西哈,position指哪改哪
      }
      buf.flip();
      buf.limit(buf.capacity);   //设置limit
      while(buf.hasRemaining()){
          int x = buf.get();      
          System.out.println(x+",");
      }
  }
}

3。创建直接缓冲区,如果创建了直接缓冲区,则JVM将尽量最大努力直接对其执行本机的IO操作
public static ByteBuffer allocateDirect(int capacity)


二:通道
通道是一个可以读取和写入数据的一种形式,
一般先放入缓冲区然后写入或读取,可进行双向操作哈

Channel接口定义
  void close() //关闭通道
  boolean isOpen(); //判断此通道是否是打开的
  
FileChannel()完成文件双向操作
public class Test{
  public static void main(String[] args){
    String[] info = {"MLDN","www.mldn.cn","www.mldnjava.cn","haha"};
     File file = new File("d:"+File.seperator+"a.txt");
     FileOutputStream output = new FileOutputStream(file);
     FileChannel fout = output.getChannel(); //得到输出通道
     ByteBuffer buf = ByteBuffer.allocate(1024);
     for(int i=0;i<info.length;i++){
       buf.put(info[i].getBytes());  //字符串变为字节数组放入缓冲区之中
     }
     buf.flip();
     fout.write(buf); //输出缓冲区的内容
     fout.close();
     output.close();
  }
}  

//注意:输出流通道只能写。。。输入流通道只能读。。哎
class Test{
  public static void main(String[] args){
    File file1 = new File("d:"+File.separator+"note.txt");
    File file2 = new File("d:"+File.separator+"outnote.txt");
    FileChannel fout  = (new FileOutputStream(file2)).getChannel(); //这样写不好,因为流对象需要关闭啦
    FileChannel fin = (new FileInputStream(file2)).getChannel();
    ByteBuffer buf = ByteBuffer.allocate(1024);
    
    int temp =0;
    while((temp = fin.read(buf)) != -1){
       buf.flip();
       fout.write(out);
       buf.clear();  //清空缓冲区
    }
    fin.close();
    fout.close();
   //input.close();
    //output.close();
  }
}

//RamdomAccessFile :较慢
FileInputStream:较慢
缓冲读取:速度较快
内存映射:最快

MappedByteBuffer:使用此种方式读取最快哈
需要将一个输入的操作流绑定在内存映射

FileChannel类的三个内存映射模式:
public static final FileChannel.MapMode.READ_ONLY //只读映射
FileChannel.MapMode.READ_WRITE //读写模式
FileChannel.MapMode.PRIVATE  //专用(写入时拷贝)映射模式


class Test{
  public static void main(String[] args){
    File file = new FIle("d:"+File.separator+"a.txt");
    FileInputStream input = null;
    input = new FileInputStream(file);
    FileChannel fm = null;
    fm = input.getChannel();
    MapperByteBuffer buf =fin.map(FileChannel.MapMode.READ_ONLY,0,file.length()); //把文件直接映射到内存,而不是一行行读
    byte data[] = new byte[(int)file.length()]; //开辟空间接收内容
    int foot = 0;
    while(buf.hasRemaining()){
       data[foot++] = buf.get(); //读取数据
    }
    System.out.println(new String(data));
    fin.close();
    input.close();
    
    
  }
}

//注意:上述操作代码是最快的,但是如果在使用以上操作代码的时候,执行的是写入操作
则有可能非常危险,因为仅仅只是改变数组中的单个元素这样的简单操作,就有可能直接修改磁盘
上的文件,因为修改数据与将数据保存在磁盘上是一样的

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics