2016-11-20 11 views
6

Я пытаюсь удалить файл в операционной системе Windows с помощью API Java IO file.delete(). Однако он терпит неудачу и возвращает false. Тот же код работает как прелесть в Ubuntu.Не удалось удалить файл в Windows с помощью Java

Я проверил, что разрешения файла позволяют программе удалить его. Также все входные и выходные потоки для файла были открыты как попытка с ресурсами.

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

Использование отладчика Я проверил и обнаружил, что в строке кода, который я удалить файл, он возвращает true для следующих вызовов API.

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

Я даже пытался добавить System.gc() прямо перед вызовом удалить, чтобы убедиться, что все потоки будут закрыты.

Не уверен, что это полезная информация, но я даже попытался использовать метод Apache commons FileUtils.forceDelete(file), и он также потерпел неудачу.

Итак, что мне здесь не хватает?

Update:

С помощью 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) 
+0

File.delete() довольно старый API. Вы можете попытаться использовать 'Files.delete (somePath)', так что, возможно, вы получите лучшую ошибку/исключение: см. Http://stackoverflow.com/questions/12139482/difference-between-filesdeletepath-and-filedelete – user140547

+0

Я обновил вопрос, за исключением того, что я получил. – dammina

+0

В Windows вы не можете удалить файл, в котором кто-либо (включая ваш собственный процесс) имеет дескриптор файла. Это отличается от Unix, где вы всегда можете удалить его (и даже использовать дескрипторы открытых файлов впоследствии). Что вы можете сделать (если это временный файл, который следует удалить), вы можете использовать deleteOnExit, это может работать до тех пор, пока ваш процесс будет единственным, у которого есть открытые filedescriptors. – eckes

ответ

0

Использование Files.delete(filePath) вместо file.delete() в file.delete() имеет некоторый вопрос относительно разрешения на окнах.

+0

посмотрите пожалуйста. – dammina

+1

Различий между этими двумя API для этого случая нет. – eckes

+0

Сообщает, что ваш файл открыт в JVM. Попробуйте закрыть файл и повторите попытку, поскольку файл, открытый JVM, не может быть удален. Надеюсь, это поможет. –

1

Добро пожаловать в 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, как правило, ничего не мешает вам удалить его, поэтому вы видите другое поведение.

0

Возможно, вы можете использовать System.Runtime.exec() для запуска команды терминала/командной строки для удаления определенного файла. Это может быть как-то зависящим от платформы, но команда, которая будет введена в функцию exec(), может отличаться среди свойств os.

Вы можете проверить эту тему, чтобы определить текущую версию программы java.

How do I programmatically determine operating system in Java?

В Linux, ваша линия будет выглядеть следующим образом:

System.Runtime.exec("rm <path to file>");