Channels和Buffers是JAVA NIO里面比较重要的两个概念,NIO正是基于Channels和Buffers进行数据操作,且数据总是从Channels读取到Buffers,或者从Buffers写入到Channels。
以FileChannel为例,如下:
FileChannel是文件写入/读取相关的通道;
产生FileChannel的方式:
下面举个例子,分别从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();
}
}
再举个文件复制的例子,有两种方式:
如下代码示例:
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用于与通道进行交互,举个例子如下,这里以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();
}
}
compact
:往buffer写数据之前调用,只清除已读取的数据,新写入的数据会添加到未读数据末尾;(
Buffer
buffer)方法
,调用Buffer的put方法
write
(
Buffer
buffer)方法
调用Buffer的get方法
参考:http://ifeve.com/java-nio-all/
原文:http://www.cnblogs.com/chenpi/p/5372786.html