通道 Channel

用于源节点和目标节点的连接,负责数据的传输,Channel可以类比为铁路,Buffer可以类比为高铁,人群就是数据。

java.nio.channels.Channel 接口主要有以下实现

  • FileChannel 文件通道,用作文件操作
  • SocketChannel 套接字通道,用作网络编程客户端
  • ServerScoketChannel 服务端套接字通道,用作网络编程服务端
  • DatagramChnnel 数据报通道,用作UDP协议数据传输数据
  1. //测试文件拷贝
  2. @Test
  3. void t1() throws IOException {
  4. String source = "/Users/liupeng/IdeaProjects/test/1.txt";
  5. String des = "/Users/liupeng/IdeaProjects/test/2.txt";
  6. FileInputStream inputStream = new FileInputStream(source);
  7. FileOutputStream outputStream = new FileOutputStream(des);
  8. //1.获取Channel
  9. FileChannel inChannel = inputStream.getChannel();
  10. FileChannel outChannel = outputStream.getChannel();
  11. //2.分配缓冲区 Buffer
  12. ByteBuffer buf = ByteBuffer.allocate(1024);
  13. // ByteBuffer buf = ByteBuffer.allocateDirect(1024);//直接使用操作系统内存
  14. //拷贝文件
  15. while (inChannel.read(buf) != -1) {
  16. buf.flip();
  17. outChannel.write(buf);
  18. buf.clear();
  19. }
  20. //关闭流和通道
  21. outChannel.close();
  22. inChannel.close();
  23. outputStream.close();
  24. inputStream.close();
  25. }
  26. //通道间数据传输
  27. @Test
  28. void t5() throws IOException {
  29. String source = "/Users/liupeng/IdeaProjects/test/1.txt";
  30. String des = "/Users/liupeng/IdeaProjects/test/3.txt";
  31. FileChannel in = FileChannel.open(Paths.get(source));
  32. FileChannel out = FileChannel.open(Paths.get(des),
  33. StandardOpenOption.CREATE,StandardOpenOption.WRITE);
  34. // in.transferTo(0, in.size(), out);
  35. out.transferFrom(in, 0, in.size());
  36. in.close();
  37. out.close();
  38. }
  39. //使用直接缓冲区完成文件的复制(内存映射文件)
  40. @Test
  41. public void t8() throws IOException {
  42. String source = "/Users/liupeng/IdeaProjects/test/1.txt";
  43. String des = "/Users/liupeng/IdeaProjects/test/5.txt";
  44. FileChannel inChannel = FileChannel.open(Paths.get(source), StandardOpenOption.READ);
  45. FileChannel outChannel = FileChannel.open(Paths.get(des),
  46. StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);
  47. //内存映射文件
  48. MappedByteBuffer inMappedBuf = inChannel.map(FileChannel.MapMode.READ_ONLY, 0, inChannel.size());
  49. MappedByteBuffer outMappedBuf = outChannel.map(FileChannel.MapMode.READ_WRITE, 0, inChannel.size());
  50. //直接对缓冲区进行数据的读写操作
  51. byte[] dst = new byte[inMappedBuf.limit()];
  52. inMappedBuf.get(dst);
  53. outMappedBuf.put(dst);
  54. inChannel.close();
  55. outChannel.close();
  56. }
  57. //分散和聚集
  58. @Test
  59. public void test4() throws IOException {
  60. String source = "/Users/liupeng/IdeaProjects/test/1.txt";
  61. String des = "/Users/liupeng/IdeaProjects/test/5.txt";
  62. RandomAccessFile sourceFile = new RandomAccessFile(source, "rw");
  63. //1. 获取通道
  64. FileChannel sourceChannel = sourceFile.getChannel();
  65. //2. 分配指定大小的缓冲区
  66. ByteBuffer buf1 = ByteBuffer.allocate(10);
  67. ByteBuffer buf2 = ByteBuffer.allocate(5);
  68. ByteBuffer buf3 = ByteBuffer.allocate(20);
  69. //3. 分散读取
  70. ByteBuffer[] buffers = {buf1, buf2,buf3};
  71. sourceChannel.read(buffers);
  72. for (ByteBuffer b : buffers) {
  73. b.flip();
  74. System.out.println(new String(b.array()));
  75. }
  76. //4. 聚集写入
  77. RandomAccessFile desFile = new RandomAccessFile(des, "rw");
  78. FileChannel desChannel = desFile.getChannel();
  79. desChannel.write(buffers);
  80. }