Изменить содержимое файла с помощью Java

Я хочу удалить часть содержимого файла с помощью java-программы, как показано ниже. Это метод записи для замены в том же файле или его следует скопировать в другой файл.

Но это удаление всего содержимого файла.

class FileReplace
{
    ArrayList<String> lines = new ArrayList<String>();
    String line = null;
    public void  doIt()
    {
        try
        {
            File f1 = new File("d:/new folder/t1.htm");
            FileReader fr = new FileReader(f1);
            BufferedReader br = new BufferedReader(fr);
            while (line = br.readLine() != null)
            {
                if (line.contains("java"))
                    line = line.replace("java", " ");
                lines.add(line);
            }
            FileWriter fw = new FileWriter(f1);
            BufferedWriter out = new BufferedWriter(fw);
            out.write(lines.toString());
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
        }
    }
    public statc void main(String args[])
    {
        FileReplace fr = new FileReplace();
        fr.doIt();
    }
}

person Adesh singh    schedule 06.12.2012    source источник
comment
я думаю, вы должны использовать имя br только один раз;)   -  person acostache    schedule 06.12.2012
comment
1) закрыть ридер после использования: br.close(); 2) что такое out в вашем коде? 3) каков результат, чего вы ожидали?   -  person Andy    schedule 06.12.2012


Ответы (6)


Я бы начал с закрытия читателя и сброса писателя:

public class FileReplace {
    List<String> lines = new ArrayList<String>();
    String line = null;

    public void  doIt() {
        try {
            File f1 = new File("d:/new folder/t1.htm");
            FileReader fr = new FileReader(f1);
            BufferedReader br = new BufferedReader(fr);
            while ((line = br.readLine()) != null) {
                if (line.contains("java"))
                    line = line.replace("java", " ");
                lines.add(line);
            }
            fr.close();
            br.close();

            FileWriter fw = new FileWriter(f1);
            BufferedWriter out = new BufferedWriter(fw);
            for(String s : lines)
                 out.write(s);
            out.flush();
            out.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String args[]) {
        FileReplace fr = new FileReplace();
        fr.doIt();
    }
}
person Mateusz    schedule 06.12.2012
comment
-1 Я не могу найти writeline в BufferWriter, а Close должно быть в нижнем регистре. - person giannis christofakis; 09.05.2014

Принятый ответ великолепен. Однако есть более простой способ замены содержимого в файле с помощью библиотеки Apache commons-io (commons-io-2.4.jar — можно использовать любые последние версии)

private void update() throws IOException{
        File file = new File("myPath/myFile.txt");
        String fileContext = FileUtils.readFileToString(file);
        fileContext = fileContext.replaceAll("_PLACEHOLDER_", "VALUE-TO-BE-REPLACED");
        FileUtils.write(file, fileContext);
 }

Примечание. Брошенные IOException должны быть перехвачены и обработаны приложением соответствующим образом.

person Sandeep Salian    schedule 07.08.2015
comment
Почему это лучше? Похоже, он делает то же самое... или, по крайней мере, просто копирует файл в строку и перезаписывает файл? Зачем вам Apache для этого? - person Sam; 07.04.2021

Моделирование чтения и записи в один и тот же файл недопустимо.

РЕДАКТИРОВАТЬ: перефразировать и быть более правильным и конкретным - чтение и запись в один и тот же файл, в том же потоке, без правильного закрытия считывателя (и сброса записи) не в порядке.

person acostache    schedule 06.12.2012
comment
Не могли бы вы уточнить, почему? - person Damian Leszczyński - Vash; 06.12.2012
comment
Да, вообще говоря, причина будет заключаться в том, что смещения в файле будут смещаться каждый раз, когда вы делаете запись, и курсор чтения не будет отслеживать это (см. принятый ответ здесь: stackoverflow.com/questions/4251058/). Тем не менее, перечитав этот вопрос, проблема здесь была не в этом (я ответил слишком быстро), а в том, чтобы не закрыть и не слить. - person acostache; 06.12.2012

Убедитесь, что:

  • close любой поток, когда они вам больше не нужны
  • В частности, перед повторным открытием для записи.
  • truncate файл, чтобы убедиться, что он сжимается, если вы пишете меньше, чем было.
  • затем напишите вывод
  • пишите отдельные строки, не полагайтесь на toString.
  • flush и close, когда вы закончите писать!

Если вы используете буферизованный ввод-вывод, вы всегда должны убедиться, что буфер очищается в конце, иначе вы можете потерять данные!

person Has QUIT--Anony-Mousse    schedule 06.12.2012
comment
Я не уверен, что он читает/пишет одновременно. Он считывает строки в список, затем записывает список в файл или, по крайней мере, пытается это сделать. - person Qwerky; 06.12.2012

Я вижу три проблемы.

Сначала вы пишете в out, который, как я предполагаю, является System.out, а не выходным потоком в файл.

Во-вторых, если вы записываете поток вывода в файл, вам нужно закрыть его.

В-третьих, метод toString() для ArrayList не будет записывать файл так, как вы ожидаете. Прокрутите список и напишите каждое String по одному. Спросите себя, нужно ли вам также писать символы новой строки.

person Qwerky    schedule 06.12.2012

Принятый ответ немного неверен. Вот правильный код.

    public class FileReplace {
List<String> lines = new ArrayList<String>();
String line = null;

public void  doIt() {
    try {
        File f1 = new File("d:/new folder/t1.htm");
        FileReader fr = new FileReader(f1);
        BufferedReader br = new BufferedReader(fr);
        while ((line = br.readLine()) != null) {
            if (line.contains("java"))
                line = line.replace("java", " ");
            lines.add(line);
        }
        fr.close();
        br.close();

        FileWriter fw = new FileWriter(f1);
        BufferedWriter out = new BufferedWriter(fw);
        for(String s : lines)
             out.write(s);
        out.flush();
                } 
        out.close();
   catch (Exception ex) {
        ex.printStackTrace();
    }
}
person Ravi K M    schedule 14.10.2016
comment
да. out.close() должен быть вне цикла. - person Ravi K M; 14.10.2016
comment
Он находится вне цикла for. Цикл for — это только следующая строка, так как фигурные скобки уже выведены. Вы поместили его за пределы блока try. Лучшим решением было бы поместить считыватели в using{...} блоков. - person Karl Gjertsen; 14.10.2016