Windows上现有文件的零星NoSuchFileException

时间:2017-02-16 17:16:35

标签: java windows nio

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);
        }}

catch子句的输出

文件尚未显示...
文件尚未显示...
文件尚未显示...
[省略一些线条]
文件在以下之后神奇地重现: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。

1 个答案:

答案 0 :(得分:0)

我认为问题在这里

java.nio.file.NoSuchFileException: C:\Users\STEFAN~1.MOS\AppData\Local\Temp\junit8070411457691609987\temp_2164

您正在尝试读取临时文件。临时文件无法保证存在。