最重要的四种Channel
- FileChannel 文件通道,用于文件的读写
- SocketChannel tcp连接,客户端服务器都能用
- ServerSocketChannel tcp连接,用于服务器
- DatagramChannel UDP连接
FileChannel
FileChannel 只能工作在阻塞模式下
获取FileChannel:通过输入输出流或者RandomAccessFile 获取
- 通过 FileInputStream 获取的 channel 只能读
- 通过 FileOutputStream 获取的 channel 只能写
- 通过 RandomAccessFile 是否能读写根据构造 RandomAccessFile 时的读写模式决定
关闭FileChannel**:
channel 必须关闭,不过调用了 FileInputStream、FileOutputStream 或者 RandomAccessFile 的 close 方法会间接地调用 channel 的 close 方法
强制写入:
操作系统出于性能的考虑,会将数据缓存,不是立刻写入磁盘。可以调用 force(true) 方法将文件内容和元数据(文件的权限等信息)立刻写入磁盘
public static void copyFile1(String sourceFilePath,String targetFilePath){var start = System.currentTimeMillis();try {@Cleanup FileInputStream fis = new FileInputStream(sourceFilePath);@Cleanup FileOutputStream fos = new FileOutputStream(targetFilePath);@Cleanup FileChannel inChannel = fis.getChannel();@Cleanup FileChannel outChannel = fos.getChannel();ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024);while(inChannel.read(buffer) != -1){//切换为读模式buffer.flip();outChannel.write(buffer);//清除buffer 变为写模式buffer.clear();}//强制刷盘outChannel.force(true);} catch (FileNotFoundException e) {System.out.println(" 源文件路径:" + sourceFilePath + "复制源文件不存在");} catch (IOException e) {System.out.println("文件复制异常" + e.getMessage());}var end = System.currentTimeMillis();System.out.println("耗时:" + (end - start));}/**** @param sourceFilePath* @param targetFilePath*/public static void copyFile2(String sourceFilePath,String targetFilePath){var start = System.currentTimeMillis();try {FileChannel sourceChannle = new FileInputStream(sourceFilePath).getChannel();FileChannel targetChannle = new FileOutputStream(targetFilePath).getChannel();long size = sourceChannle.size();//表示还剩余多少字节没有传输long left = size;while (left > 0){//底层会使用操作系统的零拷贝,一次最多传输2g的数据left -= sourceChannle.transferTo(size - left,sourceChannle.size(),targetChannle);}targetChannle.force(true);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}var end = System.currentTimeMillis();System.out.println("耗时:" + (end - start));}
SocketChannel
NIO中涉及网元连接的通道有两个,一个是SocketChannel负责连接传输,另一个ServerSocketChannel负责连接的监听
ServerSocketChannel用于服务端,而SocketChannel同时应用于服务端和客户端,对于一个连接两端都有一个负责传输的SocketChannel传输通道。
