Channel,通道,也可以理解为连接。
在传统BIO中,流(Stream)是单向的,例如FileInputStream对向只能进行读取数据的操作,而NIO中的通道是双向的,可以读写操作。
Channel在NIO中是一个接口,常用的Channel有:
FileChannel:用于文件的数据读写
DatagramChannel:用于UDP数据读写
ServerSocketChannel和SocketChannel:用于TCP读写
通道的读写函数示例,注意读写是站在通道角度看的
read(ByteBuffer dst)从通道读取数据并放到缓冲区中
write(ByteBuffer src)把缓冲区数据写到通道中
transferFrom(ReadableByteChannel src,long position,long count)把目标通道的数据复制到当前通道中
transferTo(long position,long count,WritableByteChannel target)把当前通道的数据复制到目标通道中
package NIO;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ChannelCase1 {
public static void main(String[] args) throws IOException {
String str = "Hello, channel";
FileOutputStream fileOutputStream = new FileOutputStream("e:\\test.txt");
//通过fileOutputStream获取对应的filechannel
//FileChannel真实类型是FileChannelImpl
FileChannel channel = fileOutputStream.getChannel();
//创建一个buffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
//对应的buffer就是写
buffer.put(str.getBytes());
buffer.flip();
//把buffer的数据写入到channel中,对应的buffer就是读
channel.write(buffer);
//关闭资源
fileOutputStream.close();
}
}
复制文件Demo
package NIO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ChannelCase2 {
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("e:\\test.txt");
FileChannel channel1 = fileInputStream.getChannel();
FileOutputStream fileOutputStream = new FileOutputStream("e:\\test_copy.txt");
FileChannel channel2 = fileOutputStream.getChannel();
//创建一个buffer
ByteBuffer buffer = ByteBuffer.allocate(512);
while (true){
//必须对这个buffer执行clear,也就是对标志重置,否则循环将不会退出
buffer.clear();
int read = channel1.read(buffer);
if(read == -1){
break;
}
//将buffer数据写入到channel2,也就是读取buffer数据
buffer.flip();
channel2.write(buffer);
}
fileInputStream.close();
fileOutputStream.close();
}
}
使用transferFrom简化
package NIO;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ChannelCase3 {
//针对ChannelCase2的复制文件,这里直接实验channel的拷贝
public static void main(String[] args) throws IOException {
FileInputStream fileInputStream = new FileInputStream("e:\\test.txt");
FileChannel channel1 = fileInputStream.getChannel();
FileOutputStream fileOutputStream = new FileOutputStream("e:\\test_copy.txt");
FileChannel channel2 = fileOutputStream.getChannel();
channel2.transferFrom(channel1,0,channel1.size());
fileInputStream.close();
fileOutputStream.close();
}
}