package NIOTest;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
/**
* 一:通道:用于源节点和目标节点的连接,在java nio中
* 负责缓冲区中数据的传输,channel本身不存储数据,因此需要
* 配合缓冲区进行传输
*二:通道的主要实现类
*-- FileChannel 本地
*-- SocketChannel tcp
*-- ServerSocketChannel tcp
*-- DatagramChannel udp
*
*三:获取通道
*1,支持通道的类,针对通道提供了getChannel()方法
*本地io
*FileInputStream/FileOutputStream
*RandomAccessFile
*网络
*Socket
*ServerSocket
*DatagramSocket
*
*2,在jdk1.7中的NIO,针对各个通道提供了静态方法open方法
*3,在jdk1.7中files工具类newByteChannel()
*
*
*/
public class TestChannel {
public static void main(String[] args) {
test2();
}
/**
* 利用通道完成文件的复制
* @throws IOException
*/
public static void Test1() {
FileInputStream fis=null;
FileOutputStream fos=null;
FileChannel inChannel=null;
FileChannel outChannel=null;
try {
fis=new FileInputStream("D:\\1.jpg");
fos=new FileOutputStream("D:\\2.jpg");
//获取通道
inChannel=fis.getChannel();
outChannel=fos.getChannel();
//分配指定大小的缓冲区
ByteBuffer buf=ByteBuffer.allocate(1024);
//将通道中的数据写到缓冲区去
while(inChannel.read(buf)!=-1) {
buf.flip();//切换到读取数据的模式
outChannel.write(buf);
buf.clear();//清空缓冲区
}
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(inChannel!=null) {
inChannel.close();
}
if(outChannel!=null) {
outChannel.close();
}
if(fis!=null) {
fis.close();
}
if(fos!=null) {
fos.close();
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
//使用直接缓冲区完成文件的复制(内存映射文件)
public static void test2() {
try {
FileChannel inchannel=FileChannel.open(Paths.get("D:\\1.jpg"),StandardOpenOption.READ);
/**
* StandardOpenOption.CREATE:如果文件不存在就创建,存在就覆盖
* StandardOpenOption.CREATE_NEW:如果文件不存在就创建,存在就报错
*/
//MappedByteBuffer outMappedBuf我们分配的是具有读写模式的,所以写的通道也要具有读写模式,否则报错
FileChannel outChannel=FileChannel.open(Paths.get("D:\\2.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
//现在的缓冲区就在物理内存中
//直接缓冲区就只有ByteBuffer支持
MappedByteBuffer inMapperBuf=inchannel.map(MapMode.READ_ONLY, 0, inchannel.size());
MappedByteBuffer outMappedBuf=outChannel.map(MapMode.READ_WRITE, 0, inchannel.size());
/**
* 直接对缓冲区进行数据的读写操作
*/
byte[] des=new byte[inMapperBuf.limit()];
inMapperBuf.get(des);
outMappedBuf.put(des);
inchannel.close();
outChannel.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 通道之间的数据传输(直接缓冲区的方式)
* transferFrom()
* transferTo()
*/
public static void test3() {
try {
FileChannel inchannel=FileChannel.open(Paths.get("D:\\1.jpg"),StandardOpenOption.READ);
/**
* StandardOpenOption.CREATE:如果文件不存在就创建,存在就覆盖
* StandardOpenOption.CREATE_NEW:如果文件不存在就创建,存在就报错
*/
//MappedByteBuffer outMappedBuf我们分配的是具有读写模式的,所以写的通道也要具有读写模式,否则报错
FileChannel outChannel=FileChannel.open(Paths.get("D:\\2.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
inchannel.transferTo(0, inchannel.size(), outChannel);
inchannel.close();
outChannel.close();
}catch(Exception e) {
}
}
/**
* 通道之间的数据传输(直接缓冲区的方式)
* transferFrom()
* transferTo()
*/
public static void test4() {
try {
FileChannel inchannel=FileChannel.open(Paths.get("D:\\1.jpg"),StandardOpenOption.READ);
/**
* StandardOpenOption.CREATE:如果文件不存在就创建,存在就覆盖
* StandardOpenOption.CREATE_NEW:如果文件不存在就创建,存在就报错
*/
//MappedByteBuffer outMappedBuf我们分配的是具有读写模式的,所以写的通道也要具有读写模式,否则报错
FileChannel outChannel=FileChannel.open(Paths.get("D:\\2.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE_NEW);
outChannel.transferFrom(inchannel, 0, inchannel.size());
inchannel.close();
outChannel.close();
}catch(Exception e) {
}
}
}