簡體   English   中英

Files.move(...) 拋出 FileSystemException:進程無法訪問該文件,因為它正被另一個進程使用

[英]Files.move(...) throwing FileSystemException: The process cannot access the file be cause it is being used by another process

private File moveFileTo(File usageFile, File target) {
        File movedFile = new File(target.getPath() + File.separator + usageFile.getName());
        try {
            Files.move(usageFile.toPath(), movedFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
        } catch (Exception e) {
            log.error("Error while moving {} to {}", usageFile, movedFile, e);
            throw new AppException("Cannot move usage file from " + usageFile + " to " + movedFile);
        }
        return movedFile;
    }  

在帶有 Files.move 的行中拋出 FileSystemException。 我有一堆集成測試,其中 2 個每次都失敗並出現以下堆棧跟蹤:

java.nio.file.FileSystemException: C:\Users\ANDREI~1.TAN\AppData\Local\Temp\input\test-xml-usages-file-copy.xml -> C:\Users\ANDREI~1.TAN \AppData\Local\Temp\process\test-xml-usages-file-copy.xml:進程無法訪問該文件,因為它正被另一個進程使用。

 at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) at sun.nio.fs.WindowsFileCopy.move(WindowsFileCopy.java:301) at sun.nio.fs.WindowsFileSystemProvider.move(WindowsFileSystemProvider.java:287) at java.nio.file.Files.move(Files.java:1395) at com.bisnode.usagemanagement.infrastructure.importer.file.UsageFileImporterService.moveFileTo(UsageFileImporterService.java:122) at com.bisnode.usagemanagement.infrastructure.importer.file.UsageFileImporterService.importUsagesFile(UsageFileImporterService.java:42) at com.bisnode.usagemanagement.infrastructure.importer.file.scheduler.UsageFileImportScheduler.importFiles(UsageFileImportScheduler.java:33) at com.bisnode.usagemanagement.infrastructure.importer.file.scheduler.UsageFileImportScheduler.importUsageFiles(UsageFileImportScheduler.java:23) at com.bisnode.usagemanagement.infrastructure.importer.UsageImportIntegrationTest.testEndToEndImportXmlUsages(UsageImportIntegrationTest.java:119) at com.bisnode.usagemanagement.infrastructure.importer.UsageImportIntegrationTest.testEndToEndImportXmlUsagesFromInputFileWithoutNamespace(UsageImportIntegrationTest.java:114) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686) at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131) at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140) at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84) at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115) at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105) at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45) at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at java.util.ArrayList.forEach(ArrayList.java:1259) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220) at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188) at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128) at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invokeAllTests(JUnitPlatformProvider.java:150) at org.apache.maven.surefire.junitplatform.JUnitPlatformProvider.invoke(JUnitPlatformProvider.java:124) at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)

我在考慮文件鎖定,但事實是,在我的測試中,線程被禁用,因此不存在並發問題。 我不僅嘗試了 Files.move,還嘗試了幾個庫來移動文件,但都失敗了。 該代碼在 Mac 上運行良好,但在 Windows 上運行失敗。我想我錯過了一些東西,但我不知道是什么。

更新

    public void importUsagesFile(File usageFile) {
    log.info("Received usage file to import {}, size {} bytes", usageFile.getName(), usageFile.length());
    if (!isValidUsageFile(usageFile)) {
        return;
    }

    log.info("Processing file. Move the file {} to process folder", usageFile.getName());
    File usageFileToProcess = moveFileTo(usageFile, usageFileDirectory.getProcess());
    processUsageFile(usageFileToProcess);
}  

這個方法會調用moveFileTo,實際上,在調用moveFileTo之后,會調用有try-with-resources的processUsageFile。 所以簡而言之,importUsagesFile 調用 moveFileTo,然后開始執行一些業務邏輯。
更新
所以我發現了問題,在一個測試用例中,我使用的是 FileReader,因此文件被鎖定了。 我把它放在 try-with-resources 中,現在它可以工作了:D。

這是對https://serverfault.com/q/1966/22361的跨站點欺騙。

其他東西使這些手柄保持打開狀態。 您可能會在自己的代碼中泄漏打開的文件(您是否在所有地方都使用了 try-with-resources?),或者作為測試腳本的一部分調用的其他內容存在沖突。

因此,您必須使用 Process Explorer 或類似工具(例如lsof on Linux)對其進行調試。 我會在您的代碼中放置一個斷點以捕獲條件,然后使用 Process Explorer 查找句柄。 這可能很難捕捉到,但實際上沒有其他方法可以做到。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM