package com.sico.pck01_nio;
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;
import org.junit.Test;
/**
*
- @author Administrator
- 1、通道:主要用于目标节点与源节点的连接,用于数据的传输,但是需要与缓冲区配合使用。(独立的处理器,管理io,提高cpu的利用率)
- 2、主要用到的通道:
- java.nio.channels.Channel:
-
|--FileChannel
-
|--SocketChannel
-
|--ServerSocketChannel
-
|--DatagramChannel
- 3、获取通道的方法如下:
- (1)getChannel;(Local IO:)FileInputStream/FileOutputStream/RandomAccessFile和(Net IO:)Socket/ServerSocket/DatagramSocket拥有此方法。
- (2)JDK1.7的nio2中的static open();
- (3)JDK1.7的nio中的工具类Files static newByteChannel(path, options)
- 4、通道之间的数据传输:
-
|--(1)transforFrom
-
|--(2)transforTo
*/
public class Nio02 {
/**
* 通过通道进行文件的复制
*/
@Test
public void fun01(){
try {
//1、创建输入、输出流
FileInputStream is = new FileInputStream("./img/1.jpg");
FileOutputStream os = new FileOutputStream("./img/2.jpg");
//2、根据流获取通道
FileChannel fic = is.getChannel();
FileChannel foc = os.getChannel();
//3、创建缓冲区
ByteBuffer buf = ByteBuffer.allocateDirect(1024);
//4、完成文件的复制
//通过通道读取文件到缓冲区
try {
while((fic.read(buf))!=-1){
buf.flip();//切换模式
//缓冲区的内容写到通道
foc.write(buf);
buf.clear();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(fic!=null){
try {
fic.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(foc!=null){
try {
foc.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(is!=null){
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(os!=null){
try {
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
/**
* 通过直接缓冲区完成文件的复制(内存映射文件),注意只有ByteBuffer支持
* @throws IOException
*/
@Test
public void fun02() throws IOException{
long startTime = System.currentTimeMillis();
//1、获取通道
FileChannel inChannel = FileChannel.open(Paths.get("./img/1.jpg"),StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("./img/3.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
//2、获取缓冲区,内存映射文件,现在的 缓冲区在物理内存中
MappedByteBuffer inMapBuf = inChannel.map(MapMode.READ_ONLY,0, inChannel.size());
MappedByteBuffer outMapBuf = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
//3、直接缓冲区进行读写
byte[] dst=new byte[inMapBuf.limit()];
inMapBuf.get(dst);
outMapBuf.put(dst);
inChannel.close();
outChannel.close();
long endTime=System.currentTimeMillis();
System.out.println("文件的复制所花费时间:"+(endTime-startTime));
}
/**
* 直接缓冲区(物理內存)
* @throws IOException
*/
@Test
public void fun03() throws IOException{
FileChannel inChannel = FileChannel.open(Paths.get("./img/1.jpg"),StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("./img/5.jpg"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
// inChannel.transferTo(0, inChannel.size(), outChannel);
outChannel.transferFrom(inChannel, 0, inChannel.size());
inChannel.close();
outChannel.close();
}
}