1. 程式人生 > >Java NIO深入理解通道之間資料傳輸

Java NIO深入理解通道之間資料傳輸

在Java NIO中,如果兩個通道中有一個是FileChannel,那你可以直接將資料從一個channel(通道)傳輸到另外一個channel。

通道之間資料傳輸方法:transferFrom(),transferTo()


transferFrom()

FileChannel的transferFrom()方法可以將資料從源通道傳輸到FileChannel中。

eg:

package com.lanhuigu.nio.channel;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

/**
 * FileChannel中transferFrom原始碼:
 * public abstract long transferFrom(ReadableByteChannel src, long position, long count) throws IOException;
 * FileChannel的transferFrom()方法可以將資料從源通道傳輸到FileChannel中。
 */
public class TestTransferFrom {
    /**
     * 檔案複製: 將fromFile.txt檔案內容複製到toFile.txt中
     */
    public static void main(String[] args) {
        try (
             // 指定檔案建立檔案輸入流
             FileInputStream fromFile = new FileInputStream("C:\\mycode\\fromFile.txt");
             // 指定檔案建立檔案輸出流
             FileOutputStream toFile = new FileOutputStream("C:\\mycode\\toFile.txt");
             // 獲取通道
             FileChannel fromChannel = fromFile.getChannel();
             FileChannel toChannel = toFile.getChannel()) {
             // 定義position的位置為初始位置0
             long position = 0;
             // 獲取檔案總的位元組數
             long count = fromChannel.size();
             // 從fromChannel通道緩衝區position位置開始讀取count位元組數寫入到目標通道toChannel中
             toChannel.transferFrom(fromChannel, position, count);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

方法的輸入引數position表示從position處開始向目標檔案寫入資料,count表示最多傳輸的位元組數。

如果源通道的剩餘空間小於count個位元組,則所傳輸的位元組數要小於請求的位元組數。

此外要注意,在SoketChannel的實現中,SocketChannel只會傳輸此刻準備好的資料(可能不足count位元組)。

因此,SocketChannel可能不會將請求的所有資料(count個位元組)全部傳輸到FileChannel中。


transferTo()

transferTo()方法將資料從FileChannel傳輸到其他的Channel中。

eg:

package com.lanhuigu.nio.channel;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

/**
 * FileChannel的transferTo原始碼:
 * public abstract long transferTo(long position, long count, WritableByteChannel target) throws IOException;
 * transferTo()方法將資料從FileChannel傳輸到其他的Channel中。
 */
public class TestTransferTo {
    /**
     * 檔案複製: 將fromFile.txt檔案內容複製到toFile.txt中
     */
    public static void main(String[] args) {
        try (
            // 指定檔案建立檔案輸入流
            FileInputStream fromFile = new FileInputStream("C:\\mycode\\fromFile.txt");
            // 指定檔案建立檔案輸出流
            FileOutputStream toFile = new FileOutputStream("C:\\mycode\\toFile.txt");
            // 獲取通道
            FileChannel fromChannel = fromFile.getChannel();
            FileChannel toChannel = toFile.getChannel()) {
            // 定義position的位置為初始位置0
            long position = 0;
            // 獲取檔案總的位元組數
            long count = fromChannel.size();
            // 從fromChannel通道緩衝區position位置開始讀取count位元組數寫入到目標通道toChannel中
            fromChannel.transferTo(position, count, toChannel);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

這兩個例項除了呼叫方法的FileChannel物件不一樣外,其他的都一樣。

上面所說的關於SocketChannel的問題在transferTo()方法中同樣存在。

SocketChannel會一直傳輸資料直到目標buffer被填滿。