9

file.delete()我一直在尝试使用 Java IO API删除 Windows 操作系统中的文件。但是它失败并返回false。相同的代码在 Ubuntu 中就像一个魅力。

我已验证文件的权限允许程序将其删除。此外,该文件的所有输入和输出流都已作为资源尝试打开。

try (InputStream in = new FileInputStream(localFile); OutputStream out = new FileOutputStream(destinationFileName))

使用调试器我已经测试并发现在代码行中我删除了它true为以下 API 调用返回的文件。

file.exists()
file.canRead();
file.canWrite();
file.canExecute();

我什至尝试System.gc()在调用 delete 之前添加以确保所有流都已关闭。

不确定这是否是有用的信息,但我什至尝试过使用 Apache commonsFileUtils.forceDelete(file)方法,但它也失败了。

那么我在这里错过了什么?

更新:

通过使用Files.delete(Paths.get(file.getAbsolutePath()))我得到以下错误。

java.nio.file.FileSystemException: C:\Users\thuvvareka\Desktop\temp\in\sd.xml: The process cannot access the file because it is being used by another process.
    at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:86)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
    at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
    at sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:269)
    at sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:103)
    at java.nio.file.Files.delete(Files.java:1126)
    at org.adroitlogic.x.transport.file.FileMessageInjector.finalizeProcessing(FileMessageInjector.java:161)
    at org.adroitlogic.x.transport.file.FileMessageInjector.afterProcess(FileMessageInjector.java:123)
    at org.adroitlogic.x.transport.file.FileMessageInjector.afterProcess(FileMessageInjector.java:37)
    at org.adroitlogic.x.base.trp.ScheduledMessageInjector.lambda$2(ScheduledMessageInjector.java:72)
    at org.adroitlogic.x.api.trp.MessageReceiver.lambda$receive$3(MessageReceiver.java:100)
    at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:760)
    at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:736)
    at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
    at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1962)
    at org.adroitlogic.x.core.MessageContext.lambda$createNewResponseFuture$2(MessageContext.java:459)
    at java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:760)
    at java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:736)
    at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:474)
    at java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:1962)
    at org.adroitlogic.x.core.MessageContext.completeMessageFlowSuccessfully(MessageContext.java:332)
    at org.adroitlogic.x.base.connector.EgressConnectorElement.sendMessage(EgressConnectorElement.java:185)
    at org.adroitlogic.x.base.connector.EgressConnectorElement.process(EgressConnectorElement.java:146)
    at org.adroitlogic.x.base.processor.AbstractProcessingElement.processMessage(AbstractProcessingElement.java:103)
    at org.adroitlogic.x.base.processor.TraceableProcessingElement.processMessage(TraceableProcessingElement.java:53)
    at org.adroitlogic.x.base.connector.IngressConnectorElement.receiveMessage(IngressConnectorElement.java:119)
    at org.adroitlogic.x.core.IntegrationPlatform.lambda$receive$0(IntegrationPlatform.java:81)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
4

5 回答 5

3

欢迎来到 Windows。

java.nio.file.FileSystemException: C:\Users\thuvvareka\Desktop\temp\in\sd.xml: 
The process cannot access the file because it is being used by another process.

通常,当进程在 Windows 中打开文件时,操作系统会以无法删除该文件的方式锁定该文件。如果是您的程序在您尝试删除文件时打开了该文件,请先关闭该文件,然后再将其删除。如果它是打开文件的另一个程序,那么您需要弄清楚是谁打开了它并从那里开始。

当一个进程在 Linux 中打开一个文件时,通常没有什么可以阻止您删除它,这就是您看到不同行为的原因。

于 2016-11-20T17:36:46.563 回答
2

我最近遇到了这个。我创建了一个解决方法,如果file.delete()返回 false,我检查是否file.exists()返回 true,如果是,我稍等片刻,然后再试一次,并在多次尝试后放弃。

我未经证实的怀疑是 Windows 上的病毒检查程序锁定文件以检查文件并等待允许病毒检查程序完成。

            // Remove the original file.
            if(!file.delete()) {
                // wait a bit then retry on Windows
                if (file.exists())
                {
                    for (int i = 0; i < 6; i++)
                    {
                        Thread.sleep(500);
                        System.gc();
                        if (file.delete())
                           break;
                    }
于 2019-04-30T05:50:01.607 回答
1

使用Files.delete(filePath)而不是file.delete()asfile.delete()在 Windows 上的权限方面存在一些问题。

于 2016-11-20T16:38:04.730 回答
0

我遇到过同样的问题。out.close();解决它。

只要您没有关闭它,System.gc() 就不会删除到 OutputStream 的链接。

于 2021-05-18T10:13:07.913 回答
-1

也许您可以使用 System.Runtime.exec() 运行终端/命令行命令来删除特定文件。这可能在某种程度上取决于平台,但是要输入到 exec() 函数的命令可能因操作系统属性而异。

您可以检查此线程以确定正在运行的 java 程序的当前操作系统。

如何以编程方式确定 Java 中的操作系统?

在 linux 中,您的行将如下所示:

System.Runtime.exec("rm <path to file>");
于 2016-12-26T11:13:52.720 回答