Java NIOはチャネル間のデータ転送を深く理解する

3509 ワード

前言
Github:https://github.com/yihonglei/java-all
Project:java-nio
Java NIOでは、2つのチャネルのうち1つがFileChannelである場合、1つのチャネル(チャネル)から別のチャネルにデータを直接転送することができます.
チャネル間データ転送方法:transferFrom()、transferTo()
1 transferFrom
FileChannelのtransferFrom()メソッドは、ソースチャネルからFileChannelにデータを転送することができる.
package com.lanhuigu.nio.transfer;

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 。
 *
 * @author yihonglei
 */
public class TransferFromTest {
    /**
     *     :  fromFile.txt       toFile.txt 
     */
    public static void main(String[] args) {
        try (
                //            
                FileInputStream fis = new FileInputStream("C:\\mycode\\fromFile.txt");
                //            
                FileOutputStream fos = new FileOutputStream("C:\\mycode\\toFile.txt");
                //     
                FileChannel fromChannel = fis.getChannel();
                FileChannel toChannel = fos.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にすべて転送しない可能性があります.
2、transferTo
TransferTo()メソッドは、FileChannelから他のChannelにデータを転送します.
package com.lanhuigu.nio.transfer;

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 。
 *
 * @author yihonglei
 */
public class TransferToTest {
    /**
     *     :  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();
        }
    }
}

この2つのインスタンスは、呼び出しメソッドのFileChannelオブジェクトが異なる以外は同じです.
前述したSocketChannelに関する問題はtransferTo()メソッドにおいても同様に存在する.
SocketChannelは、ターゲットbufferが満たされるまでデータを転送します.