Netty (5) -Canal

1. Introducción básica

1) El canal de NIO es similar a la transmisión, pero algunas diferencias son las siguientes:

  • El canal puede leer y escribir al mismo tiempo, mientras que la transmisión solo puede leer o escribir
  • El canal puede realizar lectura y escritura asincrónicas de datos.
  • El canal puede leer datos del búfer o escribir datos en el búfer

Canal 和 Buffer2) El flujo en BIO es unidireccional, por ejemplo, el objeto FileInputStream solo puede leer datos, mientras que el canal en NIO es bidireccional y se puede leer o escribir.

3) El canal es una interfaz de interfaz pública El canal se extiende Se puede cerrar en NIO

4) Las clases de canal más utilizadas son: FileChannel, DatagramChannel, ServerSocketChannel y SocketChannel

5) FileChannel se utiliza para la lectura y escritura de datos de archivos, DatagramChannel se utiliza para la lectura y escritura de datos UDP, ServerSocketChannel y SocketChannel se utilizan para la lectura y escritura de datos TCP.

2. Métodos comunes

2.1 clase FileChannel

FileChannel se utiliza principalmente para realizar operaciones de E / S en archivos locales. Los métodos comunes son:

método descripción
int read (ByteBuffer dst) Leer datos del canal y ponerlos en el búfer
int escribir (ByteBuffer src) Escribe los datos en el búfer en el canal.
long transferFrom (ReadableByteChannel src, posición larga, cuenta larga) Copiar datos del canal de destino al canal actual
long transferTo (posición larga, cuenta larga, destino WritableByteChannel) Copiar datos del canal actual al canal de destino

Tres, casos de aplicación

3.1 Escribir datos en un archivo local

Requisitos del caso

1), usando ByteBuffer (búfer) y FileChannel (canal), escriba "Hello, World!" En file01.txt
2), cree el archivo si no existe
3), demostración de código

public class NIOFileChannel01 {

    public static void main(String[] args) throws IOException {

        String str = "Hello,World!";

        // 创建一个输出流->channel
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\file01.txt");

        // 通过 fileOutputStream 获取对应的 FileChannel
        // 这个 fileChannel 真实类型是 FileChannelImpl
        FileChannel fileChannel = fileOutputStream.getChannel();

        // 创建一个缓冲区 ByteBuffer
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        // 将 str 放入到 byteBuffer
        byteBuffer.put(str.getBytes());

        // 对 byteBuffer 进行反转(flip)
        byteBuffer.flip();

        // 将 byteBuffer 数据写入到 fileChannel
        fileChannel.write(byteBuffer);
        fileOutputStream.close();
    }
    
}

3.2 Leer datos del archivo local

Requisitos del caso

1) Use ByteBuffer (búfer) y Channel (canal) para leer los datos en file01.txt en el programa y mostrarlos en la consola
2), asumiendo que el archivo ya existe
3), demostración de código

public class NIOFileChannel02 {

    public static void main(String[] args) throws IOException {

        // 创建文件的输入流
        File file = new File("d:\\file01.txt");
        FileInputStream fileInputStream = new FileInputStream(file);

        // 通过 fileInputStream 获取对应的 FileChannel->FileChannelImpl
        FileChannel fileChannel = fileInputStream.getChannel();

        // 创建缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate((int)file.length());

        // 将通道的数据读入到 byteBuffer 中
        fileChannel.read(byteBuffer);

        // 将 byteBuffer 中的字节数据转成字符串
        System.out.println(new String(byteBuffer.array()));

        fileInputStream.close();
    }

}

3.3 Usar un búfer para completar la lectura del archivo

Requisitos del caso

1) Use FileChannel (canal) y los métodos de lectura y escritura para completar la copia del archivo.2
) Copie un archivo de texto 1.txt y colóquelo debajo del proyecto en 2.txt
3) Use solo un búfer en todo el proceso

Use un búfer para completar la lectura del archivo

4), demostración de código

public class NIOFileChannel03 {

    public static void main(String[] args) throws IOException {

        FileInputStream fileInputStream = new FileInputStream("1.txt");
        FileChannel fileChannel01 = fileInputStream.getChannel();

        FileOutputStream fileOutputStream = new FileOutputStream("2.txt");
        FileChannel fileChannel02 = fileOutputStream.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.allocate(512);

        while (true){ // 循环读取

            // 这里有一个重要的操作,一定不要忘了
            /*public final Buffer clear() {
                position = 0;
                limit = capacity;
                mark = -1;
                return this;
            }*/
            byteBuffer.clear(); // 清空 buffer

            int read = fileChannel01.read(byteBuffer);
            System.out.println("read =" + read);
            System.out.println(new String(byteBuffer.array()));

            if(read == -1){ // 表示读取完毕
                break;
            }

            // 将 buffer 中的数据写入到 fileChannel02 --> 2.txt
            byteBuffer.flip();
            fileChannel02.write(byteBuffer);
        }

        // 关闭流
        fileInputStream.close();
        fileOutputStream.close();
    }

}

3.4 Utilice transferFrom para copiar archivos

Requisitos del caso

1), use FileChannel (canal) y el método transferFrom para completar la copia del archivo
2), copie una imagen
3), demostración del código

public class NIOFileChannel04 {

    public static void main(String[] args) throws IOException {

        // 创建相关流
        FileInputStream fileInputStream = new FileInputStream("d:\\a.jpg");
        FileOutputStream fileOutputStream = new FileOutputStream("d:\\a2.jpg");

        // 获取各个流对应的filechannel
        FileChannel sourceCh = fileInputStream.getChannel();
        FileChannel destCh = fileOutputStream.getChannel();

        // 使用 transferFrom 完成拷贝
        destCh.transferFrom(sourceCh,0,sourceCh.size());

        // 关闭通道和流
        sourceCh.close();
        destCh.close();
        fileInputStream.close();
        fileOutputStream.close();
    }

}

Supongo que te gusta

Origin blog.csdn.net/yangxshn/article/details/113393660
Recomendado
Clasificación