版权声明:如需转载请标明出处 https://blog.csdn.net/yj201711/article/details/84955432
通道(Channel):传输数据
由 java.nio.channels 包定义的。Channel表示IO源与目标打开的链接。Channel类似于传统的“流”。只不过Channel本身不能直接访问数据,Channel只能与 Buffer 进行交互
IO 改进示意图
DMA(直接存储器访问)
Java 为 Channel 接口提供的最主要实现类如下:
- FileChannel:用于读取、写入、映射和操作文件的通道。
- DatagramChannel:通过 UDP 读写网络中的数据通道。
- SocketChannel:通过 TCP 读写网络中的数据。
- ServerSocketChannel:可以监听新进来的 TCP 连接,对每一个新进来的连接都会创建一个 SocketChannel。
获取通道
本地IO:
FileInputStream/FileOutPutStream
RandomAccessFile
网络IO:
socket
ServerSocket
DatagramSocket
获取通道的其他方式是:
- jdk1.7 使用 Files 类的静态方法 newByteChannel() 获取字节通道。
- jdk1.7 通过通道的静态方法 open() 打开并返回指定通道
使用通道进行数据传输
FileInputStream / FileOutputStream 的getChannel()
FileChannle的open(Path path,OpenOpertion ... oo)方法来打开通道
package org.lanqiao.channel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
/*
* 通过本地IO获取通道 进行数据传输
*/
public class ChannelDemo {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream(new File("Notes.txt"));
FileOutputStream fos = new FileOutputStream(new File("copy.txt"));
//开辟通道
FileChannel inChannel = fis.getChannel();
FileChannel outChannel = fos.getChannel();
//分配缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
//循环将输入读入到缓冲区
while((inChannel.read(buffer)) != -1) {
//将缓冲区有读模式切换到写模式
buffer.flip();
//将缓冲区中的数据通过输出通道写出到膜裱
outChannel.write(buffer);
//清空缓冲区
buffer.clear();
}
//关闭通道
inChannel.close();
outChannel.close();
}
}
package org.lanqiao.channel;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class ChannelDemo2 {
public static void main(String[] args) throws IOException {
//打开文件输入通道
FileChannel inChannel = FileChannel.open(Paths.get("Notes.txt"), StandardOpenOption.READ);
//打开文件输出通道
FileChannel outChannel = FileChannel.open(Paths.get("copy2.txt"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
ByteBuffer buf = ByteBuffer.allocate(1024);
while((inChannel.read(buf)) != -1) {
buf.flip();
outChannel.write(buf);
buf.clear();
}
inChannel.close();
outChannel.close();
}
}
package org.lanqiao.channel;
import java.io.IOException;
import java.io.InputStream;
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;
/*
* 使用直接缓冲区(内存映射文件)完成文件复制
*/
public class ChannelDemo3 {
public static void main(String[] args) throws IOException {
FileChannel inChannel = FileChannel.open(Paths.get("Notes.txt"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("copy3.txt"), StandardOpenOption.WRITE,StandardOpenOption.READ,StandardOpenOption.CREATE);
//ByteBuffer buf = ByteBuffer.allocateDirect(1024);
//创建内存映射文件
MappedByteBuffer inMap = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
MappedByteBuffer outMap = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());
byte[] buf = new byte[inMap.limit()];
inMap.get(buf);
outMap.put(buf);
inChannel.close();
outChannel.close();
}
}
package org.lanqiao.channel;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
/*
* 通道之间直接进行文件传输(直接缓冲区)
*/
public class ChannelDemo4 {
public static void main(String[] args) throws IOException {
FileChannel inChannle = FileChannel.open(Paths.get("Notes.txt"), StandardOpenOption.READ);
FileChannel outChannel = FileChannel.open(Paths.get("copy5.txt"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
//inChannle.transferTo(0, inChannle.size(), outChannel);
outChannel.transferFrom(inChannle, 0, inChannle.size());
inChannle.close();
outChannel.close();
}
}