java,transferTo速度慢与RandomAccessFile

为什么transferTo(也就是sendfile 零拷贝)要比RandomAccessFile(随机写)要慢?

今天做了一个复制大文件的测试,分别使用transferTo和RandomAccessFile复制4G大小的文件,原本以为使用transferTo这种0拷贝的应该是最快的,但是实验发现使用RandomAccessFile加ByteBuffer的这种却是比较快的。
这里就产生问题,ByteBuffer这种一定又用户空间和内核空间的转换消耗。而transferTo理论上是没有这部分消耗,但是为什么确是RandomAccessFile这种方式快那??
求高人解析下
代码如下 test1是transferTo ,test2是RandomAccessFile

public class Test {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        test1();
        System.out.println("time1:" + (System.currentTimeMillis() - start));

        long start2 = System.currentTimeMillis();
        test2();
        System.out.println("time2:" + (System.currentTimeMillis() - start2));
    }

    public static void test1() throws IOException {
        // FileUtils.copyFile(new File("D:\\iso\\CentOS-7-x86_64-DVD-2009.iso"), new File("D:\\iso\\CentOS-7-x86_64-DVD-2009.iso3"));

        File sourceFile = new File("D:\\iso\\CentOS-7-x86_64-DVD-2009.iso");
        FileInputStream fis = new FileInputStream(sourceFile);
        FileChannel fisChannel = fis.getChannel();

        FileOutputStream fos = new FileOutputStream("D:\\iso\\CentOS-7-x86_64-DVD-2009.iso2");
        FileChannel fosChannel = fos.getChannel();
        //将fisChannel通道的数据,写入到fosChannel通道
        long size = fisChannel.size();
        long cpSize = 0;
        do {
            fisChannel.transferTo(cpSize, size - cpSize, fosChannel);
            cpSize = fosChannel.size();
            System.out.println(cpSize);
        } while (cpSize < size);
        // fosChannel.transferFrom(fisChannel,0,size);
        // fisChannel.transferTo(0, fisChannel.size(), fosChannel);

        System.out.println(fosChannel.size());
        fis.close();
        fos.flush();
        fos.close();

    }

    public static void test2() throws IOException {
        RandomAccessFile randomAccessFile1 = new RandomAccessFile("D:\\iso\\CentOS-7-x86_64-DVD-2009.iso", "r");
        RandomAccessFile randomAccessFile2 = new RandomAccessFile("D:\\iso\\CentOS-7-x86_64-DVD-2009.iso3", "rw");
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024 * 1024);
        while (true) {
            byteBuffer.clear();
            int read = randomAccessFile1.getChannel().read(byteBuffer);
            if (read == -1) {
                break;
            }
            byteBuffer.flip();
            randomAccessFile2.getChannel().write(byteBuffer);
        }
        randomAccessFile1.close();
        randomAccessFile2.close();
    }
}

两种可能的原因:1.文件系统的不同。某些文件系统(如 NTFS)支持零拷贝技术,而其他文件系统(如 ext3)则不支持。如果使用的是不支持零拷贝技术的文件系统,那么 transferTo 方法的性能就会比使用 RandomAccessFile 进行随机写要慢。

2.设备的不同。在某些情况下,transferTo 方法的性能可能受到磁盘或网络设备的限制。如果使用的是性能较差的设备,那么 transferTo 方法的性能也可能比使用 RandomAccessFile 进行随机写要慢。