Ошибка удаления / перемещения файла

В приведенном ниже коде я пытаюсь выбрать xml-файлы из ArrayList xmls, где xmls.get (i) - это абсолютный путь к файлу с расширением .xml. Если этот файл не может быть проанализирован Document, генерируется исключение, и файл перемещается в другой каталог. Однако я не могу переместить или удалить файл, хотя могу скопировать его в каталог destFile. Значения последнего оператора if возвращают true для f.exists(), f.canRead(), f.canWrite(), f.canExecute, но возвращает false дляf.renameTo(destFile);

for(int i=0; i<xmls.size(); i++){
    boolean delete = false;

    try {
        File f = new File(xmls.get(i));
        File destFile = new File(structDir + "/badXMLs/" + f.getName());

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(f);
        doc.getDoctype();

    } catch (Exception e) {
        File f = new File(xmls.get(i));
        File destFile = new File(structDir + "/badXMLs/" + f.getName());

        System.out.println(f.getName());
        delete = true;
    } 

    if(delete){
        File f = new File(xmls.get(i));
        File destFile = new File(structDir + "/badXMLs/" + f.getName());

        System.out.println(f.exists());
        System.out.println(f.canRead());
        System.out.println(f.canWrite());
        System.out.println(f.canExecute());

        System.out.println(f.renameTo(destFile));
    }
}

person Codey McCodeface    schedule 03.01.2012    source источник
comment
Одна из причин заключается в том, что ваш целевой каталог находится в другой точке монтирования, так ли это?   -  person fge    schedule 03.01.2012
comment
} catch (Exception e) { - этот код ловит все исключения; вы должны поймать конкретное исключение, которое вас интересует (например, «файл не может быть проанализирован с помощью документа»). В противном случае вы попытаетесь удалить файл, если, например, в вашем коде есть NullPointerException или другая ошибка.   -  person artbristol    schedule 03.01.2012


Ответы (2)


По умолчанию DocumentBuilder не закрывает файл при получении исключения. Самый простой способ избежать этого - использовать FileInputStream и закрыть его самостоятельно, например:

FileInputStream fis = null;

try {
    File f = new File(xmls.get(i));
    File destFile = new File(structDir + "/badXMLs/" + f.getName());
    fis = new FileInputStream(f);

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(fis); // parse the FileInputStream, not the File
    doc.getDoctype();

} catch (Exception e) {
    if (fis != null) {
        fis.close();
    }

    File f = new File(xmls.get(i));
    File destFile = new File(structDir + "/badXMLs/" + f.getName());

    System.out.println(f.getName());
    delete = true;
} 

Он не закрывает его, поэтому, по крайней мере, под окнами вы не можете его удалить или переименовать. Обратите внимание, что вам также не нужно каждый раз создавать DocumentBuilder.

person Matthew Farwell    schedule 03.01.2012

Не уверен в ответах, которые предлагают вам вызвать close () для файлового объекта, поскольку java.io.File не имеет такого метода, но я думаю, что они движутся в правильном направлении.

Я бы предложил переключиться на использование FileInputStream и закрыть его.

метод синтаксического анализа может принимать либо объект File, либо FileInputStream, так что это должно быть нормально.

person Rob H    schedule 03.01.2012