通道 Channel
Channel 是一个对象,可以通过他读取和写入数据。拿NIO与原来的I/O做比较,通道就是像是流。
正如前面提到的,所有数据都是通过Buffer对象来处理。永远不会将字节直接写入通道中,相反,是将数据写入包含一个或者多个字
节的缓冲区。同样,不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
public class CopyFileDemo {
public static void main(String[] args){
try {
CopyFile();
randowaccessfileCopy();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 比较IO操作的性能比较:
* 1、内存映射的最快
* 2、NIO读写文件第二块
* 3、使用了缓存的IO流
* 4、无缓存的IO流最慢
*/
//通过文件通道实现文件的复制
public static void CopyFile() throws Exception {
//创建一个输入文件的通道
FileChannel fcin = new FileInputStream("E:\\Java_IO\\第8章.zip").getChannel();
//创建一个输出文件的通道
FileChannel fcout = new FileOutputStream("E:\\Java_IO\\test\\第8章.zip").getChannel();
//创建一个字节缓冲区,并申请内存空间大小为10245字节
ByteBuffer buf = ByteBuffer.allocate(1024);
while(fcin.read(buf)!=-1) {
buf.flip(); //缓冲区进行反转
fcout.write(buf); //缓冲区数组反转后写文件时就不用0,len这种格式了
buf.clear();
}
fcout.close();
fcin.close();
System.out.println("coyt success...");
}
//通过内存映射实现文件的复制:MappedByteBuffer
public static void randowaccessfileCopy() {
try {
RandomAccessFile in = new RandomAccessFile("E:\\\\Java_IO\\\\第8章.zip", "r");
RandomAccessFile out = new RandomAccessFile("E:\\Java_IO\\test\\第8章.zip", "rw");
FileChannel fin = in.getChannel();
FileChannel fout = out.getChannel();
long size = fin.size();//文件通道输入流的字节大小,返回长整型long
//输入的映射缓冲流区
MappedByteBuffer min = fin.map(MapMode.READ_ONLY, 0, size);
//输出的映射缓冲流区
MappedByteBuffer mout = fout.map(MapMode.READ_WRITE, 0, size);
for(int i=0;i<size;i++) {
mout.put(min.get());
/**
min.get()将输入缓冲流中的内容转换成字节
mout.put(byte bytes)将字节bytes写入到输出缓冲流中
*/
}
//关闭(关闭通道时会自动写入数据)
fout.close();
fin.close();
out.close();
in.close();
System.out.println("copy success...");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}