файл.delete () возвращает false, даже если файл.существует(), файл.canRead (), file.canWrite (), file.canExecute () все возвращает true
Я пытаюсь удалить файл, после записи что-то в нем, с FileOutputStream
. Это код, который я использую для написания:
private void writeContent(File file, String fileContent) {
FileOutputStream to;
try {
to = new FileOutputStream(file);
to.write(fileContent.getBytes());
to.flush();
to.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
как видно, я смываю и закрыть поток, но когда я пытаюсь удалить file.delete()
возвращает false.
Я проверил перед удалением, чтобы увидеть, если файл существует, и: file.exists()
,file.canRead()
,file.canWrite()
,file.canExecute()
все возвращают true. Сразу после вызова этих методов я пытаюсь file.delete()
и возвращает false.
есть ли что-нибудь, что я сделал неправильно?
16 ответов:
еще одна ошибка в Java. Я редко нахожу их, только второй в моей 10-летней карьеры. Это мое решение, как уже говорили другие. Я пустоты использовал
System.gc()
. Но здесь, в моем случае, это абсолютно важно. Странно? Да!finally { try { in.close(); in = null; out.flush(); out.close(); out = null; System.gc(); } catch (IOException e) { logger.error(e.getMessage()); e.printStackTrace(); } }
это было довольно странно трюк, который работал. Дело в том, что когда я ранее читал содержимое файла, я использовал
BufferedReader
. Прочитав,я закрыл буфер.тем временем я переключился, и теперь я читаю контент с помощью
FileInputStream
. Также после окончания чтения я закрываю поток. И теперь это работает.проблема в том, что у меня нет объяснения этому.
Я не знаю
BufferedReader
иFileOutputStream
несовместимы.
я попробовал эту простую вещь, и она, кажется, работает.
file.setWritable(true); file.delete();
это работает для меня.
если это не работает попробуйте запустить приложение Java с sudo, если на linux и в качестве администратора, когда на windows. Просто чтобы убедиться, что Java имеет права изменять свойства файла.
прежде чем пытаться удалить/переименовать какой-то файл, вы должны убедиться, что все читатели или писатели (например:
BufferedReader
/InputStreamReader
/BufferedWriter
) закрыт.при попытке чтения / записи данных из / в файл, файл удерживается процессом и не освобождается до завершения выполнения программы. Если вы хотите выполнить операции удаления / переименования до завершения программы, то вы должны использовать
close()
метод, который поставляется сjava.io.*
классы.
как прокомментировал Джон Скит, вы должны закрыть свой файл в finally {...} блок, чтобы убедиться, что он всегда закрыт. И вместо того, чтобы проглатывать исключения с помощью e.printStackTrace, просто не ловите и не добавляйте исключение в сигнатуру метода. Если вы не можете по какой-либо причине, по крайней мере сделать это:
catch(IOException ex) { throw new RuntimeException("Error processing file XYZ", ex); }
Теперь вопрос №2:
Что делать, если вы сделаете это:
... to.close(); System.out.println("Please delete the file and press <enter> afterwards!"); System.in.read(); ...
сможете ли вы удалить файл?
кроме того, файлы покраснел, когда они закрыты. Я использую IOUtils.близко(...), поэтому я использую метод flush, чтобы убедиться, что содержимое файла есть, прежде чем я попытаюсь закрыть его (IOUtils.closeQuietly не бросает исключения). Что-то вроде этого:
... try { ... to.flush(); } catch(IOException ex) { throw new CannotProcessFileException("whatever", ex); } finally { IOUtils.closeQuietly(to); }
поэтому я знаю, что содержимое файла находится там. Как это обычно имеет значение для меня, что содержимое файла записывается, а не если файл может быть закрыт или нет, это действительно не имеет значения, если файл был закрыт или нет. В вашем случае, поскольку это имеет значение, я бы рекомендовал закрыть файл самостоятельно и обрабатывать любые исключения в соответствии.
нет причин, по которым вы не можете удалить этот файл. Я бы посмотрел, кто держит этот файл. В unix/linux вы можете использовать утилиту lsof, чтобы проверить, какой процесс имеет блокировку файла. В windows можно использовать проводник процессов.
для lsof это так же просто, как сказать:
lsof /path/and/name/of/the/file
для Process explorer вы можете использовать меню найти и ввести имя файла, чтобы показать вам дескриптор, который укажет вам на процесс блокировки файла.
вот некоторый код, который делает то, что я думаю, что вам нужно сделать:
FileOutputStream to; try { String file = "/tmp/will_delete.txt"; to = new FileOutputStream(file ); to.write(new String("blah blah").getBytes()); to.flush(); to.close(); File f = new File(file); System.out.print(f.delete()); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }
Он отлично работает на OS X. Я не тестировал его на windows, но я подозреваю, что он должен работать и на Windows. Я также признаю, что вижу некоторое неожиданное поведение при обработке файлов Windows w.r.t.
Если вы работаете в Eclipse IDE, это может означать, что вы не закрыли файл в предыдущем запуске приложения. Когда у меня было такое же сообщение об ошибке при попытке удалить файл, это было причиной. Кажется, Eclipse IDE не закрывает все файлы после завершения работы приложения.
надеюсь, это поможет. Я столкнулся с аналогичной проблемой, когда я не мог удалить свой файл после того, как мой java-код сделал копию содержимого в другую папку. После обширного поиска в Интернете я явно объявил все переменные, связанные с каждой операцией с файлом, и вызвал метод close () каждого объекта операции с файлом и установил их в NULL. Кроме того, есть функция под названием Система.gc (), который очистит отображение ввода-вывода файла (я не уверен, я просто говорю, что дано в интернете сайты.)
вот мой пример кода:
public void start() { File f = new File(this.archivePath + "\" + this.currentFile.getName()); this.Copy(this.currentFile, f); if(!this.currentFile.canWrite()){ System.out.println("Write protected file " + this.currentFile.getAbsolutePath()); return; } boolean ok = this.currentFile.delete(); if(ok == false){ System.out.println("Failed to remove " + this.currentFile.getAbsolutePath()); return; } } private void Copy(File source, File dest) throws IOException { FileInputStream fin; FileOutputStream fout; FileChannel cin = null, cout = null; try { fin = new FileInputStream(source); cin = fin.getChannel(); fout = new FileOutputStream(dest); cout = fout.getChannel(); long size = cin.size(); MappedByteBuffer buf = cin.map(FileChannel.MapMode.READ_ONLY, 0, size); cout.write(buf); buf.clear(); buf = null; cin.close(); cin = null; fin.close(); fin = null; cout.close(); cout = null; fout.close(); fout = null; System.gc(); } catch (Exception e){ this.message = e.getMessage(); e.printStackTrace(); } }
ответ, когда вы загружаете файл, вам нужно применить метод "закрыть", в любой строке кода, работает для меня
однажды в ruby возникла проблема, когда файлы в windows нуждались в" fsync", чтобы на самом деле иметь возможность разворачиваться и перечитывать файл после его записи и закрытия. Возможно, это аналогичное проявление (и если да, то я думаю, что ошибка windows, действительно).
ни одно из перечисленных здесь решений не сработало в моей ситуации. Мое решение состояло в том, чтобы использовать цикл while, пытаясь удалить файл, с 5-секундным (настраиваемым) ограничением для безопасности.
File f = new File("/path/to/file"); int limit = 20; //Only try for 5 seconds, for safety while(!f.delete() && limit > 0){ synchronized(this){ try { this.wait(250); //Wait for 250 milliseconds } catch (InterruptedException e) { e.printStackTrace(); } } limit--; }
использование вышеуказанного цикла работало без необходимости выполнять ручной сбор мусора или устанавливать поток в нуль и т. д.
проблема может быть в том, что файл по-прежнему рассматривается как открытый и заблокированный программой; или, возможно, это компонент вашей программы, в котором он был открыт, поэтому вы должны убедиться, что используете
dispose()
метод для решения этой проблемы. то естьJFrame frame; .... frame.dispose();
вы должны закрыть все потоки или использовать try-with-resource block
static public String head(File file) throws FileNotFoundException, UnsupportedEncodingException, IOException { final String readLine; try (FileInputStream fis = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); LineNumberReader lnr = new LineNumberReader(isr)) { readLine = lnr.readLine(); } return readLine; }
Если файл.delete () отправляет false, тогда в большинстве случаев ваш дескриптор Bufferedreader не будет закрыт. Просто близко, и это, кажется, работает для меня нормально.
у меня была такая же проблема на Windows. Я использовал, чтобы прочитать файл в строку скала на строку с
Source.fromFile(path).getLines()
Теперь я читаю его в целом с
import org.apache.commons.io.FileUtils._ // encoding is null for platform default val content=readFileToString(new File(path),null.asInstanceOf[String])
который закрывает файл правильно после чтения и теперь
new File(path).delete
строительство.
для Eclipse / NetBeans
перезагрузите IDE и запустите свой код снова это только трюк работа для меня после одного часа долгой борьбы.
вот мой код:
File file = new File("file-path"); if(file.exists()){ if(file.delete()){ System.out.println("Delete"); } else{ System.out.println("not delete"); } }
выход:
удалить