首页 > 编程语言 > 详细

【JAVA NIO】Channels和Buffers

时间:2016-04-09 23:36:04      阅读:268      评论:0      收藏:0      [点我收藏+]

Channels和Buffers是JAVA NIO里面比较重要的两个概念,NIO正是基于Channels和Buffers进行数据操作,且数据总是从Channels读取到Buffers,或者从Buffers写入到Channels

通道(Channel)

  • 可以从通道写输入,也可以读数据;
  • 通道的数据是跟Buffer进行交互的,数据可以读到Buffer,也可以从Buffer写数据到通道;
  • 还可以异步读写数据;

以FileChannel为例,如下:

FileChannel

FileChannel是文件写入/读取相关的通道;

产生FileChannel的方式:

  • 从FileOutputStream中获取;
  • 从RandomAccessFile中获取;
  • 从FileInputStream中获取;

下面举个例子,分别从FileOutputStream、RandomAccessFile、FileInputStream中获取文件通道,进行相关写入/读取操作;

package com.pichen.io;

import java.nio.*;
import java.nio.channels.*;
import java.io.*;

public class GetChannel {
    private static final int BSIZE = 1024;

    public static void main(String[] args) throws Exception {
        // 创建文件输出字节流
        FileOutputStream fos = new FileOutputStream("data.txt");
        //得到文件通道
        FileChannel fc = fos.getChannel();
        //往通道写入ByteBuffer
        fc.write(ByteBuffer.wrap("Some text ".getBytes()));
        //关闭流
        fos.close();

        //随机访问文件
        RandomAccessFile raf = new RandomAccessFile("data.txt", "rw");
        //得到文件通道
        fc = raf.getChannel();
        //设置通道的文件位置 为末尾
        fc.position(fc.size()); 
        //往通道写入ByteBuffer
        fc.write(ByteBuffer.wrap("Some more".getBytes()));
        //关闭
        raf.close();
        
        //创建文件输入流
        FileInputStream fs = new FileInputStream("data.txt");
        //得到文件通道
        fc = fs.getChannel();
        //分配ByteBuffer空间大小
        ByteBuffer buff = ByteBuffer.allocate(BSIZE);
        //从通道中读取ByteBuffer
        fc.read(buff);
        //调用此方法为一系列通道写入或相对获取 操作做好准备
        buff.flip();
        //从ByteBuffer从依次读取字节并打印
        while (buff.hasRemaining()){
            System.out.print((char) buff.get());
        }
        fs.close();
    }
} 

再举个文件复制的例子,有两种方式:

  • 打开一个FileChannel用于读,另一个用于写;
  • 直接调用transferTo或者transferFrom方法传输通道之间的数据;

如下代码示例:

package com.pichen.io;

import java.nio.*;
import java.nio.channels.*;
import java.io.*;

public class ChannelCopy {
    private static final int BSIZE = 1024;

    public static void main(String[] args) throws Exception {
        //获取文件输入输出字节流
        FileInputStream fis = new FileInputStream("C:\\test.jpg");
        FileOutputStream fos = new FileOutputStream("C:\\test_copy.jpg");
        
        //从文件输入输出字节流中获取通道
        FileChannel fci = fis.getChannel();
        FileChannel fco = fos.getChannel();
        //分配ByteBuffer空间大小
        ByteBuffer buffer = ByteBuffer.allocate(BSIZE);
        
        //第一种种数据拷贝方式,直接往输入通道写数据
        while (fci.read(buffer) != -1) {
            //为写入操作做准备
            buffer.flip(); 
            //往输出通道写入buffer
            fco.write(buffer);
            //清空buffer,重置内部指针
            buffer.clear(); 
        }
        
        //第二种数据拷贝方式,利用transferTo或者transferFrom方式
        FileOutputStream fos2 = new FileOutputStream("C:\\test_copy2.jpg");
        FileChannel fco2 = fos.getChannel();
        fci.transferTo(0, fci.size(), fco2);
        
        
        fis.close();
        fos.close();
        fos2.close();
    }
}

缓冲区(Buffer)

buffer用于与通道进行交互,举个例子如下,这里以ByteBuffer为例;

package com.pichen.io;

import java.nio.*;
import java.nio.channels.*;
import java.io.*;

public class GetChannel {
    private static final int BSIZE = 1024;

    public static void main(String[] args) throws Exception {

        // 随机访问文件
        RandomAccessFile raf = new RandomAccessFile("C:\\data.txt", "rw");
        // 得到文件通道
        FileChannel fc = raf.getChannel();

        ByteBuffer bf = ByteBuffer.allocate(BSIZE);

        int bytesRead = fc.read(bf); // read into buffer.
        while (bytesRead != -1) {
            // 通过flip()方法将Buffer从写模式切换到读模式
            bf.flip();
            while (bf.hasRemaining()) {
                // 每次读取一个字节
                System.out.print((char) bf.get());

            }

            // 清空缓存,准备往缓存写数据
            bf.clear();
            bytesRead = fc.read(bf);
        }

        // 关闭
        raf.close();
    }
}

Buffer基本方法

  • flip方法:从buffer读数据之前调用,从写模式切换到读模式;
  • clear:往buffer写数据之前调用,全部清除;
  • compact:往buffer写数据之前调用,只清除已读取的数据,新写入的数据会添加到未读数据末尾;

Buffer基本属性

  • capacity:buffer空间大小;
  • position:读写数据时的指针,指向当前位置;
  • limit:读数据时,表示当前可读数据的大小;写数据时,即buffer大小=capacity;

Buffer的类型

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

Buffer中写数据

  • 从Channel写到Buffer,调用通道的read(Buffer buffer)方法
  • put()方法写到Buffer里,调用Buffer的put方法

Buffer中读取数据

  • 从Buffer读取数据到Channel,调用通道的write(Buffer buffer)方法
  • 使用get()方法从Buffer中读取数据,调用Buffer的get方法

 

参考:http://ifeve.com/java-nio-all/

【JAVA NIO】Channels和Buffers

原文:http://www.cnblogs.com/chenpi/p/5372786.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!