TL; DR :我有一个测试,它产生一个新进程,在无限循环中读写文件。过了一会儿,我的测试再次杀死了生成的进程并检查写入的文件是否没有损坏。
偶尔测试失败并带有NoSuchFileException
。但是,该文件确实存在:如果我在Files.exists(..)
的文件中查看其存在(即,调用NoSuchFileException
) &# 34;重新出现"几毫秒后。
// 1. create some random file data
byte[] data = new byte[4096 * 2];
Random random = new Random();
for (int i = 0; i < data.length; i++) {
data[i] = (byte) random.nextInt();
}
for (int i = 0;; i++) {
// 2. write random data into file
File file = tempDir.newFile("temp_" + i);
Files.write(file.toPath(), data);
// 3. spawn proccess
Process process = spawnProcess(file);
Thread.sleep(ThreadLocalRandom.current().nextInt(500, 1000));
// 4. kill process
process.destroyForcibly();
assertThat(process.isAlive(), is(false));
try {
// 5. make sure file was not corrupted
assertThat(Files.readAllBytes(file.toPath()).length, greaterThan(0));
} catch (NoSuchFileException e) {
long start = System.currentTimeMillis();
while (!Files.exists(file.toPath())) {
System.out.println("File not visible yet...");
}
System.out.println("File reappeared magically after: " + (System.currentTimeMillis() - start) + "ms");
e.printStackTrace();
throw e;
}
}
public static void main(String[] args) throws IOException {
// 1. path of the file that was created by the test is passed as argument
Path file = Paths.get(args[0]);
byte[] data = Files.readAllBytes(file);
while (true) {
// 2. try to write the file transactionally
// - write to temp file first and then move it atomically to original file
Path tempFile = Files.createTempFile(file.getFileName().toString(), null);
Files.copy(file, tempFile, COPY_ATTRIBUTES, REPLACE_EXISTING);
Files.write(tempFile, data);
Files.move(tempFile, file, ATOMIC_MOVE, REPLACE_EXISTING);
}}
文件尚未显示...
文件尚未显示...
文件尚未显示...
[省略一些线条]
文件在以下之后神奇地重现:22ms
NoSuchFileException
的堆栈跟踪:
java.nio.file.NoSuchFileException: C:\Users\STEFAN~1.MOS\AppData\Local\Temp\junit8070411457691609987\temp_2164
at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230)
at java.nio.file.Files.newByteChannel(Files.java:361)
at java.nio.file.Files.newByteChannel(Files.java:407)
at java.nio.file.Files.readAllBytes(Files.java:3152)
...
有人可以解释这个NoSuchFileException
会如何发生吗?我已经禁用了磁盘的写缓存,但问题仍然存在。我使用Windows 10和JDK 1.8.0_102-b14。
答案 0 :(得分:0)
我认为问题在这里
java.nio.file.NoSuchFileException: C:\Users\STEFAN~1.MOS\AppData\Local\Temp\junit8070411457691609987\temp_2164
您正在尝试读取临时文件。临时文件无法保证存在。