Пожалуйста, рассмотрим следующий пример Java класс (pom.xml ниже):Странное поведение при удалении файлов с Files.delete()
package test.filedelete;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import org.apache.commons.io.IOUtils;
public class Main
{
public static void main(String[] args) throws IOException
{
byte[] bytes = "testtesttesttesttesttesttesttesttesttest".getBytes();
InputStream is = new ByteArrayInputStream(bytes);
Path tempFileToBeDeleted = Files.createTempFile("test", "");
OutputStream os = Files.newOutputStream(tempFileToBeDeleted);
IOUtils.copy(is, os);
deleteAndCheck(tempFileToBeDeleted);
// breakpoint 1
System.out.println("\nClosing stream\n");
os.close();
deleteAndCheck(tempFileToBeDeleted);
}
private static void deleteAndCheck(Path file) throws IOException
{
System.out.println("Deleting file: " + file);
try
{
Files.delete(file);
}
catch (NoSuchFileException e)
{
System.out.println("No such file");
}
System.out.println("File really deleted: " + !Files.exists(file));
System.out.println("Recreating deleted file ...");
try
{
Files.createFile(file);
System.out.println("Recreation successful");
}
catch (IOException e)
{
System.out.println("Recreation not possible, exception: " + e.getClass().getName());
}
}
}
я пишу в FileOutputStream и попытаться удалить файл после без закрытия Поток первый. Это была моя оригинальная проблема и, конечно, неправильная, но это приводит к некоторым странным наблюдениям.
При запуске основного метода на Windows 7 она производит следующий вывод:
Deleting file: C:\Users\MSCHAE~1\AppData\Local\Temp\test6100073603559201768
File really deleted: true
Recreating deleted file ...
Recreation not possible, exception: java.nio.file.AccessDeniedException
Closing stream
Deleting file: C:\Users\MSCHAE~1\AppData\Local\Temp\test6100073603559201768
No such file
File really deleted: true
Recreating deleted file ...
Recreation successful
- Почему первый вызов Files.delete() не бросить исключение?
- Почему следующий вызов Files.exist() возвращает false?
- Почему невозможно создать файл заново?
Что касается последнего вопроса, я заметил, что файл по-прежнему отображается в проводнике при остановке в точке останова 1. Когда вы завершаете JVM, тогда файл будет удален в любом случае. После закрытия потока deleteAndCheck() работает так, как ожидалось.
Мне кажется, что удаление не распространяется на ОС перед закрытием потока, и API файлов не отражает это правильно.
Может кто-нибудь объяснить, что здесь происходит?
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>filedelete</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
</project>
Обновление для осветления
файл исчезает в Windows Explorer, если поток закрыт и Files.delete() называется - последняя операция триггеры - или если вызван файл.delete(), не закрывая поток, и JVM завершается.
Какая ОС это? Если Unix-like, можете ли вы попробовать и распечатать разрешения родительского каталога? – fge
И, кстати, вы можете напрямую использовать 'Files.copy()' для копирования содержимого 'InputStream' в' Path'; нет необходимости в IOUtils – fge
Попробуйте положить точку останова на 'Files.delete (file);' и затем пройти мимо нее. В этот момент файл фактически исчезает из окна проводника? Я подозрительно, что каким-то образом удаление успешно завершается, но окна хранят файл, потому что есть другая ссылка, открытая для него. Это может быть что-то низкоуровневое в том, как работают окна. Я бы не ожидал такого же в системе Posix (например: Linux). –