gpt4 book ai didi

缓冲区的搬运工——通道 Channel

转载 作者:知者 更新时间:2024-03-13 12:18:03 25 4
gpt4 key购买 nike

一 点睛

通道用于数据的双向传输,即一个通道既可以用于读数据,又可以用于写数据。注意,这点不同于 I/O 中的 Stream,Stream 是单向的(只能是输入流或输出流)。

在 NIO 中,就是使用“缓冲区+通道”进行数据的传输。具体地讲,就是使用通道对缓冲区、文件或套接字进行数据传输。

可以把缓冲区理解为“池塘”,把通道理解为“排水管”。

NIO 中的 Channel(通道)是一个接口,有以下几种常见的实现类。

  • FileChannel
  • SocketChannel
  • ServerSocketChannel
  • DatagramChannel

如果药获取 Channel 对象,可以使用下表。

| <br>FileInputStream<br><br>FileOutputStream<br><br>RandomAccessFile<br> | <br>本地 I/O 类。这些类中都提供了 FileChannel getChannel() 方法,可以用于获取 FileChannel 对象。<br> |
| <br>Socket<br><br>ServerSocket<br><br>DatagramSocket<br> | <br>网络 I/O 类。这些类提供了 XXXChannel getChannel() 方法,可以用于获取不同类型的 Channel 对象。<br> |
| <br>FileChannel 等各个 Channel 实现类<br> | <br>Channel 实现类中,都提供了用于获取 Channel 对象的 open() 方法。例如,FileChannel 类中的 open() 方法:public static FileChannel open(Path path, OpenOption... options) throws IOException<br> |
| <br>Files<br> | <br>public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)<br> |

二 缓冲区文件复制

1 代码

package nio;

import java.io.FileInputStream;
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.Pipe;
import java.nio.charset.CharacterCodingException;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class NIODemo {
    // 使用非直接缓冲区复制文件
    public static void test2() throws IOException {
        long start = System.currentTimeMillis();
        FileInputStream input = new FileInputStream("g:\\navicat.chm");
        FileOutputStream out = new FileOutputStream("g:\\navicat_copy1.chm");
        // 获取通道
        FileChannel inChannel = input.getChannel();
        FileChannel outChannel = out.getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);

        while (inChannel.read(buffer) != -1) {
            buffer.flip();
            outChannel.write(buffer);
            buffer.clear();
        }
        if (outChannel != null) outChannel.close();
        if (inChannel != null) inChannel.close();
        if (out != null) out.close();
        if (input != null) input.close();
        long end = System.currentTimeMillis();
        System.out.println("复制操作消耗的时间(毫秒):" + (end - start));
    }

    // 使用直接缓冲区复制文件
    public static void test2_2() throws IOException {
        long start = System.currentTimeMillis();
        FileInputStream input = new FileInputStream("g:\\navicat.chm");
        FileOutputStream out = new FileOutputStream("g:\\navicat_copy2.chm");
        // 获取通道
        FileChannel inChannel = input.getChannel();
        FileChannel outChannel = out.getChannel();
        ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

        while (inChannel.read(buffer) != -1) {
            buffer.flip();
            outChannel.write(buffer);
            buffer.clear();
        }
        if (outChannel != null) outChannel.close();
        if (inChannel != null) inChannel.close();
        if (out != null) out.close();
        if (input != null) input.close();
        long end = System.currentTimeMillis();
        System.out.println("复制操作消耗的时间(毫秒):" + (end - start));
    }

    public static void main(String[] args) throws IOException {
        test2();
        System.out.println("--------------------------");
        test2_2();
    }
}

2 测试

复制操作消耗的时间(毫秒):162


复制操作消耗的时间(毫秒):137

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com