Пожалуйста, рассмотрите следующий пример Java-класса (pom.xml ниже):
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 и пытаюсь удалить файл после этого, не закрывая сначала Stream. Это была моя оригинальная проблема и, конечно, неправильная, но это приводит к некоторым странным наблюдениям.
При запуске основного метода в 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?
- Почему не удается создать файл заново?
Что касается последнего вопроса, я заметил, что файл все еще отображается в проводнике при остановке в точке останова. Когда вы завершаете 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, если поток закрыт. И вызывается имя файла Files.delete() - последние триггеры операции, или если был вызван файл .delete(), не закрывая поток, а JVM завершается.