codestory

Die Anleitung zu Java GatheringByteChannel

  1. GatheringByteChannel
  2. Methods
  3. write(ByteBuffer[])
  4. write(ByteBuffer[], int, int)
  5. Example 1

1. GatheringByteChannel

Wenn Sie gerade erst mit Java NIO beginnen, lesen Sie zuerst die folgenden Artikel, um mehr über die Grundlagen zu erfahren:
  • Java Nio
Wie Sie wissen, ist WritableByteChannel eine Interface, die eine Methode zum Schreiben von bytes aus einem ByteBuffer bereitstellt. GatheringByteChannel ist eine Erweiterung von WritableByteChannel, die Methoden zum Sammeln von Schreibvorgängen (gathering write) bereitstellt. In einem einzigen Aufruf werden bytes aus mehreren ByteBuffer(s) in den GatheringByteChannel geschrieben.
public interface GatheringByteChannel extends WritableByteChannel
GatheringByteChannel channel =...; // (GatheringByteChannel)Channels.newChannel(fileOS);
ByteBuffer[] buffers = new ByteBuffer[]{buf1, buf2, buf3};
channel.write(buffers);
Die Hierarchie der Interface und Klassen zu GatheringByteChannel:

2. Methods

Die Methoden sind in der Interface GatheringByteChannel definiert:
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;

public long write(ByteBuffer[] srcs) throws IOException;
Die von der Interface WritableByteChannel geerbten Methoden:
public int write(ByteBuffer src) throws IOException;
Die von der Interface Channel geerbten Methoden:
public boolean isOpen();  
public void close() throws IOException;

3. write(ByteBuffer[])

public long write(ByteBuffer[] srcs) throws IOException;
Schreibt eine Folge von bytes aus vielen gegebenen ByteBuffer in diesen GatheringByteChannel. Die Methode gibt die Anzahl der geschriebenen bytes zurück oder gibt -1 zurück, wenn das Ende des Kanals erreicht wurde.
Der Aufruf dieser Methode ist äquivalent zu:
gatheringByteChannel.write(srcs, 0, srcs.length);
Es kann jeweils nur ein Schreibvorgang auf dem Channel stattfinden. Dies bedeutet, dass, wenn ein Thread eine Schreiboperation auf einem Channel einleitet, andere Threads nicht auf diesem Channel schreiben können, sie werden blockiert, bis die Operation abgeschlossen ist. Je nach Typ vom Channel können andere Operationen IO gleichzeitig mit der Schreiboperation ausgeführt werden.

4. write(ByteBuffer[], int, int)

public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;
Schreiben Sie eine Folge von bytes aus einem Array von ByteBuffer in diesen GatheringByteChannel, vom Index offset bis offset+length-1. Die Methode gibt die Anzahl der geschriebenen bytes zurück oder gibt -1 zurück, wenn das Ende des Channels erreicht wurde.
Der Aufruf dieser Methode ist äquivalent zu:
ByteBuffer[] srcs2 = new ByteBuffer[] {srcs[offset], srcs[offset+1], .., srcs[offset+length-1]};

gatheringByteChannel.write(srcs2);
Es kann jeweils nur ein Schreibvorgang auf dem Channel stattfinden. Dies bedeutet, dass, wenn ein Thread eine Schreiboperation auf einem Channel einleitet, andere Threads nicht auf diesem Channel schreiben können, sie werden blockiert, bis die Operation abgeschlossen ist. Je nach Typ vom Channel können andere Operationen IO gleichzeitig mit der Schreiboperation ausgeführt werden.

5. Example 1

Beispiel: Schreiben Sie ein Programm, das eine Datei kopiert, verwendet ScatteringByteChannel zum Lesen der Eingabedatei und verwendet GatheringByteChannel zum Schreiben der Datei.
GatheringByteChannel_ex1.java
package org.o7planning.gatheringbytechannel.ex;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.ScatteringByteChannel;

public class GatheringByteChannel_ex1 {

    // Windows: C:/somepath/test-file.txt
    private static final String inputFilePath = "/Volumes/Data/test/in-file.txt";

    private static final String outputFilePath = "/Volumes/Data/test/out-file.txt";

    public static void main(String[] args) throws IOException {
        try (// Input:
                FileInputStream fis = new FileInputStream(inputFilePath);
                ScatteringByteChannel inChannel = (ScatteringByteChannel) Channels.newChannel(fis);
                // Output:
                FileOutputStream fos = new FileOutputStream(outputFilePath);
                GatheringByteChannel outChannel = (GatheringByteChannel) Channels.newChannel(fos);) { // try

            ByteBuffer buf1 = ByteBuffer.allocate(10);
            ByteBuffer buf2 = ByteBuffer.allocate(15);
            ByteBuffer buf3 = ByteBuffer.allocate(10);

            ByteBuffer[] buffers = new ByteBuffer[] { buf1, buf2, buf3 };

            long bytesRead = -1;
            while ((bytesRead = inChannel.read(buffers)) != -1) {
                for (int i = 0; i < buffers.length; i++) {
                    System.out.println(" --- buffer[" + i + "] ---");
                    ByteBuffer buffer = buffers[i];
                    // Set limit = current position; position = 0;
                    buffer.flip();
                    outChannel.write(buffer);
                    buffer.clear();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}