Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-返回流或通道上的close()后,它是否完成了所有作业?_Java_Linux_Io_Filesystems_Testng - Fatal编程技术网

Java-返回流或通道上的close()后,它是否完成了所有作业?

Java-返回流或通道上的close()后,它是否完成了所有作业?,java,linux,io,filesystems,testng,Java,Linux,Io,Filesystems,Testng,在linux上编写与字节传输相关的Java代码时,遇到了一些疑问 代码 FileChannelTest.java:(一个TestNG测试类) 执行结果: (在64位Linux3.x,ext4文件系统上使用Java8,如果需要的话,使用4个cpu) (1) 如果启用testCopyViaTransfer()中的延迟: (2) 如果禁用testCopyViaTransfer()中的延迟: 您可以看到第二种方法的执行情况差别很大,16ms与173ms,这是个疑问 代码使用单个线程,因此当testCop

linux上编写与字节传输相关的Java代码时,遇到了一些疑问

代码 FileChannelTest.java:(一个TestNG测试类)

执行结果: (在64位
Linux3.x
ext4
文件系统上使用
Java8
,如果需要的话,使用4个cpu)

(1) 如果启用
testCopyViaTransfer()
中的延迟:

(2) 如果禁用
testCopyViaTransfer()
中的延迟:

您可以看到第二种方法的执行情况差别很大,16ms173ms,这是个疑问

代码使用单个线程,因此当
testCopyViaBuffer()
开始执行时,
testCopyViaTransfer()
close()
已经返回

我还测试了这一点,目标文件很重要,因为当两种方法使用不同的目标文件时,第二种方法不会太慢,无论是否调用
delay()

问题是:
  • stream
    channel
    上的
    close()
    返回后(特别是对于本地文件,而不是远程套接字),它是否完成了所有有关下属资源的工作?或者,下属资源是否准备好再次使用
  • 如果是的话,那么是什么原因导致2测试中的差异,是操作系统(内核)相关的机制,Java无法控制
  • 有哪些分析工具可用于检查此类问题(如果有)

是的,它在FileChannel和AsynchronousFileChannel上都是同步操作。@Matt你的意思是说
延迟()
无关紧要,我想,我想知道为什么测试结果差别如此之大。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

import org.testng.annotations.Test;

/**
 * FileChannel test
 * 
 * @author eric
 * @date Sep 1, 2012 7:16:10 PM
 */
@Test(singleThreaded = true)
public class FileChannelTest {
    private String sourcePath = "/home/eric/desktop/a.zip";
    private String targetPath = "/tmp/a.zip";

    @Test(dependsOnMethods = { "testCopyViaTransfer" })
    public void testCopyViaBuffer() throws IOException, InterruptedException {
        copyViaBuffer(new File(sourcePath), new File(targetPath));
        // delay();
    }

    @Test
    public void testCopyViaTransfer() throws IOException, InterruptedException {
        copyViaTransfer(new File(sourcePath), new File(targetPath));
        delay();
    }

    // make thread sleep a while, so that reduce effect to subsequence operation if any shared resource,
    private void delay(long milliseconds) throws InterruptedException {
        Thread.sleep(milliseconds);
    }

    private void delay() throws InterruptedException {
        delay(500);
    }

    /**
     * copy file via buffer,
     * 
     * @param sourceFile
     * @param targetFile
     * @throws IOException
     */
    private void copyViaBuffer(File sourceFile, File targetFile) throws IOException {
        long startTime = System.currentTimeMillis();

        FileInputStream fis = new FileInputStream(sourceFile);
        FileOutputStream fos = new FileOutputStream(targetFile);

        // get channel,
        FileChannel readFc = fis.getChannel();
        FileChannel writeFc = fos.getChannel();

        ByteBuffer buf = ByteBuffer.allocate(1024 * 32); // 32Kb

        // copy via buffer,
        while (readFc.read(buf) != -1) {
            buf.flip(); // prepare for write,
            writeFc.write(buf);
            buf.clear(); // prepare for read,
        }

        // close
        readFc.close();
        writeFc.close();

        fis.close();
        fos.close();

        System.out.printf("[%s] total time: [%d ms]\n", "copy via buffer", System.currentTimeMillis() - startTime);
    }

    /**
     * copy file via transfer,
     * 
     * @param sourceFile
     * @param targetFile
     * @throws IOException
     */
    private void copyViaTransfer(File sourceFile, File targetFile) throws IOException {
        long startTime = System.currentTimeMillis();

        FileInputStream fis = new FileInputStream(sourceFile);
        FileOutputStream fos = new FileOutputStream(targetFile);

        // get channel,
        FileChannel readFc = fis.getChannel();
        FileChannel writeFc = fos.getChannel();

        // transfer
        readFc.transferTo(0, readFc.size(), writeFc);

        // close
        readFc.close();
        writeFc.close();

        fis.close();
        fos.close();

        System.out.printf("[%s] total time: [%d ms]\n", "copy via transfer", System.currentTimeMillis() - startTime);
    }
}
[copy via transfer] total time: [11 ms]
[copy via buffer] total time: [16 ms]
[copy via transfer] total time: [11 ms]
[copy via buffer] total time: [173 ms]