betacode

Руководство Java GatheringByteChannel

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

1. GatheringByteChannel

Если вы только начинаете работать с Java NIO, сначала прочитайте следующие статьи, чтобы узнать больше об основах:
  • Java Nio
Как вы знаете, WritableByteChannel - это интерфейс, который предоставляет метод записи bytes из ByteBuffer. GatheringByteChannel - это расширение от WritableByteChannel, которое предоставляет методы для сбора записи (gathering write). За один вызов bytes из нескольких ByteBuffer(s) будут записаны в GatheringByteChannel.
public interface GatheringByteChannel extends WritableByteChannel
GatheringByteChannel channel =...; // (GatheringByteChannel)Channels.newChannel(fileOS);
ByteBuffer[] buffers = new ByteBuffer[]{buf1, buf2, buf3};
channel.write(buffers);
Иерархия интерфейсов и классов, относящихся к GatheringByteChannel:

2. Methods

Методы определены в interface GatheringByteChannel:
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;

public long write(ByteBuffer[] srcs) throws IOException;
Методы, унаследованные от interface WritableByteChannel:
public int write(ByteBuffer src) throws IOException;
Методы, унаследованные от interface Channel:
public boolean isOpen();  
public void close() throws IOException;

3. write(ByteBuffer[])

public long write(ByteBuffer[] srcs) throws IOException;
Записывает последовательность bytes в этот GatheringByteChannel из многих заданных ByteBuffer. Метод возвращает количество записанных bytes или возвращает -1, если достигнут конец канала.
Вызов этого метода эквивалентен:
gatheringByteChannel.write(srcs, 0, srcs.length);
Одновременно может выполняться только одна операция записи на Channel. Это означает, что если один thread инициирует операцию записи на Channel, другие thread не могут выполнять запись на этом Channel, они блокируются (block) до завершения операции. Другие операции IO могут выполняться одновременно с операцией записи в зависимости от типа Channel.

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

public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;
Запишите последовательность bytes в этотGatheringByteChannel из массива ByteBuffer, от индекса offset до offset+length-1. Метод возвращает количество записанных bytes или возвращает -1, если достигнут конец канала.
Вызов этого метода эквивалентен:
ByteBuffer[] srcs2 = new ByteBuffer[] {srcs[offset], srcs[offset+1], .., srcs[offset+length-1]};

gatheringByteChannel.write(srcs2);
Одновременно может выполняться только одна операция записи на Channel. Это означает, что если один thread инициирует операцию записи на Channel, другие thread не могут выполнять запись на этом Channel, они блокируются (block) до завершения операции. Другие операции IO могут выполняться одновременно с операцией записи в зависимости от типа Channel.

5. Example 1

Например: Напишите программу для копирования файлов, которая использует ScatteringByteChannel для чтения входного файла и использует GatheringByteChannel для записи файла.
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();
        }
    }
}