Java NIO分散/聚集或向量I/O


在Java NIO中,通道提供了稱為分散/聚集或向量I/O的重要功能。 這是一種簡單但功能強大的技術,通過這種技術,使用單個write()函式將位元組從一組緩衝區寫入流,並且可以使用單個read()函式將位元組從流讀取到一組緩衝區中。

Java NIO已經內建了分散/聚集支援。它可以用於從頻道讀取和寫入頻道。

分散讀取

「分散讀取」用於將資料從單個通道讀取多個緩衝區中的資料。

下面來看看分散原理的說明:

下面是執行分射讀取操作的程式碼範例:

public interface ScatteringByteChannel extends ReadableByteChannel  
{  
    public long read (ByteBuffer [] argv) throws IOException;  
    public long read (ByteBuffer [] argv, int length, int offset) throws IOException;  
}

聚集寫入

「聚集寫入」用於將資料從多個緩衝區寫入單個通道。

下面來看看聚集原則的簡單說明:

下面來看看看執行聚集寫入操作的程式碼範例:

public interface GatheringByteChannel extends WritableByteChannel  
{  
    public long write(ByteBuffer[] argv) throws IOException;  
    public long write(ByteBuffer[] argv, int length, int offset) throws IOException;  
}

基本散點/聚集範例

下面來看看兩個緩衝區的簡單例子。 第一個緩衝區儲存亂數,第二個緩衝區使用分散/聚集機制儲存寫入的資料:

package com.yiibai;

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

public class ScatterGatherIO {
    public static void main(String params[]) {
        String data = "Scattering and Gathering example shown in tw511.com";
        gatherBytes(data);
        scatterBytes();
    }

    /*
     * gatherBytes() is used for reading the bytes from the buffers and write it
     * to a file channel.
     */
    public static void gatherBytes(String data) {
        String relativelyPath = System.getProperty("user.dir");
        // The First Buffer is used for holding a random number
        ByteBuffer buffer1 = ByteBuffer.allocate(8);
        // The Second Buffer is used for holding a data that we want to write
        ByteBuffer buffer2 = ByteBuffer.allocate(400);
        buffer1.asIntBuffer().put(420);
        buffer2.asCharBuffer().put(data);
        GatheringByteChannel gatherer = createChannelInstance(relativelyPath+"/testout.txt", true);
        // Write the data into file
        try {
            gatherer.write(new ByteBuffer[] { buffer1, buffer2 });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * scatterBytes() is used for reading the bytes from a file channel into a
     * set of buffers.
     */
    public static void scatterBytes() {
        String relativelyPath = System.getProperty("user.dir");
        // The First Buffer is used for holding a random number
        ByteBuffer buffer1 = ByteBuffer.allocate(8);
        // The Second Buffer is used for holding a data that we want to write
        ByteBuffer buffer2 = ByteBuffer.allocate(400);
        ScatteringByteChannel scatter = createChannelInstance(relativelyPath+"/testout.txt", false);
        // Reading a data from the channel
        try {
            scatter.read(new ByteBuffer[] { buffer1, buffer2 });
        } catch (Exception e) {
            e.printStackTrace();
        }
        // Read the two buffers seperately
        buffer1.rewind();
        buffer2.rewind();

        int bufferOne = buffer1.asIntBuffer().get();
        String bufferTwo = buffer2.asCharBuffer().toString();
        // Verification of content
        System.out.println(bufferOne);
        System.out.println(bufferTwo);
    }

    public static FileChannel createChannelInstance(String file, boolean isOutput) {
        FileChannel FChannel = null;
        try {
            if (isOutput) {
                FChannel = new FileOutputStream(file).getChannel();
            } else {
                FChannel = new FileInputStream(file).getChannel();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return FChannel;
    }
}

在上述程式中,第一個緩衝區在控制台上列印隨機輸出,第二個緩衝區在控制台上列印「Scattering and Gathering example shown in tw511.com」

它還用「Scattering and Gathering example shown in tw511.com」替換testout.txt檔案的內容。

420
Scattering and Gathering example shown in tw511.com