файл.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 85

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");
  }
}

выход:

удалить