Java-返回流或通道上的close()后,它是否完成了所有作业?
在linux上编写与字节传输相关的Java代码时,遇到了一些疑问 代码 FileChannelTest.java:(一个TestNG测试类) 执行结果: (在64位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
Linux3.x
,ext4
文件系统上使用Java8
,如果需要的话,使用4个cpu)
(1) 如果启用testCopyViaTransfer()
中的延迟:
(2) 如果禁用testCopyViaTransfer()
中的延迟:
您可以看到第二种方法的执行情况差别很大,16ms与173ms,这是个疑问
代码使用单个线程,因此当testCopyViaBuffer()
开始执行时,testCopyViaTransfer()
的close()
已经返回
我还测试了这一点,目标文件很重要,因为当两种方法使用不同的目标文件时,第二种方法不会太慢,无论是否调用delay()
问题是:
- 在
或stream
上的channel
返回后(特别是对于本地文件,而不是远程套接字),它是否完成了所有有关下属资源的工作?或者,下属资源是否准备好再次使用close()
- 如果是的话,那么是什么原因导致2测试中的差异,是操作系统(内核)相关的机制,Java无法控制
- 有哪些分析工具可用于检查此类问题(如果有)
延迟()
无关紧要,我想,我想知道为什么测试结果差别如此之大。
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]