Удаление и переименование файла

Итак, я пытаюсь удалить строку данных из файла, что я успешно сделал, открыв новый файл и записав всю информацию, которая не соответствует данным, которые я хотел бы удалить. Проблема в том, что после того, как я это сделал, я хотел бы удалить свой исходный файл, а затем переименовать новый файл, исключая информацию, которую я хотел удалить, с тем же именем, что и исходный файл. Для этого я добавил код, но по какой-то причине он не работает.

public static void delete() throws IOException
{
    File inputFile = new File("Elements.txt");
    File tempFile = new File("myTempFile.txt");

    BufferedReader reader = new BufferedReader(new FileReader(inputFile));
    BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));

    String element = JOptionPane.showInputDialog(null, "Enter the name of the Element you wish to delete.", "Remove an Element.", JOptionPane.INFORMATION_MESSAGE);;
    String currentLine;

    while((currentLine = reader.readLine()) != null) {
        String trimmedLine = currentLine.trim();
        if(trimmedLine.startsWith(element)) continue;
        writer.write(currentLine + System.getProperty("line.separator"));
    }
    writer.close(); 
    reader.close(); 

    inputFile.delete();
    tempFile.renameTo(inputFile);

    JOptionPane.showMessageDialog(null, "Data has been removed from the file: Elements.txt");
}

Как вы можете видеть внизу, у меня есть следующие строки:

inputFile.delete();

tempFile.renameTo(inputFile);

Эти строки предназначены для удаления моего исходного файла (inputFile), а затем переименования моего нового файла (tempFile) в имя файла, которое было у исходного файла. Однако после запуска кода я просто получаю файл с именем «myTempFile.txt», который успешно удалил нужную мне строку данных, но мой исходный файл все еще присутствует, и он не был удален, и новый файл не был переименован в исходный файл.

Есть идеи, почему это происходит?


person W. Ahmed    schedule 10.01.2015    source источник
comment
Вы где-то проверяете исключение ввода-вывода или просто отбрасываете его? Я предполагаю, что удаление не выполняется и вызывает исключение.   -  person Alan    schedule 11.01.2015


Ответы (3)


Используйте java.nio.file API. Это 2015 год.

final Path src = Paths.get("Elements.txt").toAbsolutePath();
final Path tmp = src.resolveSibling("Elements.txt.new");

try (
    final BufferedReader reader = Files.newBufferedReader(src, StandardCharsets.UTF_8);
    final BufferedWriter writer = Files.newBufferedWriter(tmp, StandardCharsets.UTF_8,
        StandardOpenOption.CREATE_NEW);
) {
    // yadda yadda
}

Files.move(tmp, src, StandardCopyOption.REPLACE_EXISTING);

File ненадежно. Так было всегда.

person fge    schedule 10.01.2015
comment
Это java.nio.file.Path. Вы ведь используете Java 7+? - person fge; 11.01.2015
comment
Сообщает мне «попробуйте» без «уловки», когда вы открываете программу чтения и записи, и да, у меня есть Java 7+, и я нашел класс для импорта - person W. Ahmed; 11.01.2015
comment
Вы уверены, что копируете точный синтаксис, который я использую? Обратите внимание, что это пара скобок сразу после try, а не пара скобок! - person fge; 11.01.2015
comment
Поэтому я просто решил запустить его без попытки чтения и записи, и я получаю это сообщение об ошибке: java.nio.file.AccessDeniedException: null (в sun.nio.fs.WindowsException), которое отображается в этой строке: Files .move (tmp, src, StandardCopyOption.REPLACE_EXISTING, - person W. Ahmed; 11.01.2015
comment
Я предполагаю, что вам не удалось закрыть читателя и писателя. Вот почему вы ДОЛЖНЫ использовать оператор try-with-resources, как я это делаю в коде. Это обеспечит закрытие обоих. - person fge; 11.01.2015
comment
Понятно, но какие ресурсы вы вкладываете в пример читателя и писателя? - person W. Ahmed; 11.01.2015
comment
Я не понимаю вашего вопроса ... Ресурсы здесь - это читатель и сам писатель. См. здесь. - person fge; 11.01.2015
comment
Я имею в виду, когда я пробую на ридере и писателе, он говорит мне «попробуй» без «уловки», так что я ставлю, чтобы уловить? - person W. Ahmed; 11.01.2015
comment
Подождите, вы читали то, что я сказал выше? Сразу после try это пара скобок (()), а не скобок ({}). Код компилируется по мере написания. - person fge; 11.01.2015
comment
О, я сначала попробовал это, но это выглядело очень неудобно, например: i.imgur.com/BdGdb1s. png, поэтому я решил, что это опечатка, и заключил в скобки. - person W. Ahmed; 11.01.2015
comment
Ну нет, это парни. И не обязательно под рукой. Команда try-with-resources делает это сама. - person fge; 11.01.2015
comment
Понятно, я пошел дальше и сделал это, но я не понимаю, что я здесь делаю не так: i.imgur.com/Fr95A3t.png - person W. Ahmed; 11.01.2015
comment
1. перед открывающей скобкой отсутствует закрывающая скобка; 2. удалите строки writer.close() и reader.close() после блока try. Так же, как и мой код. - person fge; 11.01.2015
comment
Хорошо, попробуйте удалить Files.move() с помощью StandardCopyOption.ATOMIC_MOVE. Если после этого вы все еще получаете эту ошибку, у вас проблема с разрешением. - person fge; 11.01.2015
comment
Вы имеете в виду заменить? После этого я получаю следующее: i.imgur.com/HClyD5b.png, я я уже импортировал java.nio.file.StandardCopyOption в мою программу, поэтому не уверен, почему это происходит - person W. Ahmed; 11.01.2015
comment
Я совсем не это имел в виду ... Я хотел заменить последний try / catch только на Files.move(tmp, src, StandardCopyOption.REPLACE_EXISTING). - person fge; 11.01.2015
comment
ОК, см. Редактирование сообщения. Но вы должны были понять, что я имел в виду. Пожалуйста, ознакомьтесь с javadoc для классов, которые я использую. - person fge; 11.01.2015
comment
А, я вижу, я изменил код, и теперь он дает мне исключение FileSystemsException и говорит, что не может получить доступ к файлу, потому что он используется другим процессом, у меня нет файла txt, открытого в фоновом режиме - person W. Ahmed; 11.01.2015
comment
Вы уверены, что это не ваше приложение имеет дескриптор в каком-то другом месте? - person fge; 11.01.2015

в таком случае я бы начал возиться, читать документацию и, возможно, немного погуглить. Но я тоже дам вам ответ!

inputFile.delete ();

Это может пойти не так, например, если ваш файл открыт в текстовом редакторе. К счастью, delete() возвращает логическое значение, попробуйте это проверить!

Также, как правильно заметил Нильс, File.renameTo() совершенно ненадежен, если у вас есть доступ к Java 7, используйте альтернативу files.nio. В Java 7 вы можете использовать Files.move(Path source, Path target, CopyOption... options)

Документы для файлов Java 7: http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html.

person NooBxGockeL    schedule 10.01.2015

Но у меня сам ваш код работает правильно. Я только меняю путь к файлу и убеждаюсь, что файл не открывается в редакторе

public class NewClass {

public static void main(String[] args) {
    try {
        delete();
    } catch (IOException ex) {
        Logger.getLogger(NewClass.class.getName()).log(Level.SEVERE, null, ex);
    }
}

public static void delete() throws IOException {
    File inputFile = new File("C:\\Users\\olyjosh\\Desktop\\Elements.txt");
    File tempFile = new File("C:\\Users\\olyjosh\\Desktop\\myTempFile.txt");

    BufferedReader reader = new BufferedReader(new FileReader(inputFile));
    BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));

    String element = JOptionPane.showInputDialog(null, "Enter the name of the Element you wish to delete.", "Remove an Element.", JOptionPane.INFORMATION_MESSAGE);;
    String currentLine;

    while ((currentLine = reader.readLine()) != null) {
        String trimmedLine = currentLine.trim();
        if (trimmedLine.startsWith(element)) {
            continue;
        }
        writer.write(currentLine + System.getProperty("line.separator"));
    }
    writer.close();
    reader.close();

    inputFile.delete();
    tempFile.renameTo(inputFile);

    JOptionPane.showMessageDialog(null, "Data has been removed from the file: Elements.txt");
}

}
person olyjosh    schedule 10.01.2015
comment
Эй, что именно ты имеешь в виду, говоря об изменении пути? Я попробовал ваше предложение, поместив инструкцию try and catch в начало моей процедуры, и я получаю сообщение о том, что не могу найти символ - класс NewClass - person W. Ahmed; 13.01.2015
comment
Путь, по которому находятся эти файлы - в моем случае он находится в каталоге рабочего стола Windows. Как видите, NewClass - это имя класса, который я использую при выполнении вашего кода. Поэтому вам следует изменить NewClass на имя вашего класса, в котором вы определили этот самый метод. - person olyjosh; 18.01.2015