Вопрос-ответ

Java Replace Line In Text File

Java Заменяет строку в текстовом файле

Как мне заменить строку текста, найденную в текстовом файле?

У меня есть строка, такая как:

Do the dishes0

И я хочу обновить его с помощью:

Do the dishes1

(и наоборот)

Как мне это сделать?

ActionListener al = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JCheckBox checkbox = (JCheckBox) e.getSource();
if (checkbox.isSelected()) {
System.out.println("Selected");
String s = checkbox.getText();
replaceSelected(s, "1");
} else {
System.out.println("Deselected");
String s = checkbox.getText();
replaceSelected(s, "0");
}
}
};

public static void replaceSelected(String replaceWith, String type) {

}

Кстати, я хочу заменить ТОЛЬКО прочитанную строку. НЕ весь файл.

Переведено автоматически
Ответ 1

Внизу у меня есть общее решение для замены строк в файле. Но сначала, вот ответ на конкретный вопрос. Вспомогательная функция:

public static void replaceSelected(String replaceWith, String type) {
try {
// input the file content to the StringBuffer "input"
BufferedReader file = new BufferedReader(new FileReader("notes.txt"));
StringBuffer inputBuffer = new StringBuffer();
String line;

while ((line = file.readLine()) != null) {
inputBuffer.append(line);
inputBuffer.append('\n');
}
file.close();
String inputStr = inputBuffer.toString();

System.out.println(inputStr); // display the original file for debugging

// logic to replace lines in the string (could use regex here to be generic)
if (type.equals("0")) {
inputStr = inputStr.replace(replaceWith + "1", replaceWith + "0");
} else if (type.equals("1")) {
inputStr = inputStr.replace(replaceWith + "0", replaceWith + "1");
}

// display the new file for debugging
System.out.println("----------------------------------\n" + inputStr);

// write the new string with the replaced line OVER the same file
FileOutputStream fileOut = new FileOutputStream("notes.txt");
fileOut.write(inputStr.getBytes());
fileOut.close();

} catch (Exception e) {
System.out.println("Problem reading file.");
}
}

Затем вызовите его:

public static void main(String[] args) {
replaceSelected("Do the dishes", "1");
}

Исходное содержимое текстового файла:


Помыл посуду0
Покормил собаку0
Убрался в комнате1


Вывод:


Помой посуду0
Накорми собаку0
Убрался в моей комнате1
----------------------------------
Помой посуду1
Накорми собаку0
Убрался в моей комнате1


Новое содержимое текстового файла:


Помой посуду1
Покорми собаку0
Убрал свою комнату1



И в качестве примечания, если текстовый файл был:


Помой посуду1
Покорми собаку0
Убрал свою комнату1


и вы использовали метод replaceSelected("Do the dishes", "1");, это просто не изменило бы файл.


Поскольку этот вопрос довольно специфичен, я добавлю здесь более общее решение для будущих читателей (исходя из названия).

// read file one line at a time
// replace line as you read the file and store updated lines in StringBuffer
// overwrite the file with the new lines
public static void replaceLines() {
try {
// input the (modified) file content to the StringBuffer "input"
BufferedReader file = new BufferedReader(new FileReader("notes.txt"));
StringBuffer inputBuffer = new StringBuffer();
String line;

while ((line = file.readLine()) != null) {
line = ... // replace the line here
inputBuffer.append(line);
inputBuffer.append('\n');
}
file.close();

// write the new string with the replaced line OVER the same file
FileOutputStream fileOut = new FileOutputStream("notes.txt");
fileOut.write(inputBuffer.toString().getBytes());
fileOut.close();

} catch (Exception e) {
System.out.println("Problem reading file.");
}
}
Ответ 2

Начиная с Java 7, это очень легко и интуитивно понятно сделать.

List<String> fileContent = new ArrayList<>(Files.readAllLines(FILE_PATH, StandardCharsets.UTF_8));

for (int i = 0; i < fileContent.size(); i++) {
if (fileContent.get(i).equals("old line")) {
fileContent.set(i, "new line");
break;
}
}

Files.write(FILE_PATH, fileContent, StandardCharsets.UTF_8);

По сути, вы считываете весь файл в a List, редактируете список и, наконец, записываете список обратно в файл.

FILE_PATH представляет Path файл.

Ответ 3

Делимся опытом работы с Java Util Stream

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public static void replaceLine(String filePath, String originalLineText, String newLineText) {
Path path = Paths.get(filePath);
// Get all the lines
try (Stream<String> stream = Files.lines(path, StandardCharsets.UTF_8)) {
// Do the line replace
List<String> list = stream.map(line -> line.equals(originalLineText) ? newLineText : line)
.collect(Collectors.toList());
// Write the content back
Files.write(path, list, StandardCharsets.UTF_8);
} catch (IOException e) {
LOG.error("IOException for : " + path, e);
e.printStackTrace();
}
}

Использование

replaceLine("test.txt", "Do the dishes0", "Do the dishes1");
Ответ 4

Если замена имеет разную длину:


  1. Читайте файл, пока не найдете строку, которую хотите заменить.

  2. Считайте в память часть после текста, который вы хотите заменить, полностью.

  3. Обрежьте файл в начале той части, которую вы хотите заменить.

  4. Написать замену.

  5. Запишите оставшуюся часть файла с шага 2.

Если замена имеет ту же длину:


  1. Читайте файл, пока не найдете строку, которую хотите заменить.

  2. Установите позицию файла в начало части, которую вы хотите заменить.

  3. Замена записи, перезапись части файла.

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

Также имейте в виду: строки Java представляют собой текст в Юникоде, в то время как текстовые файлы представляют собой байты с определенной кодировкой. Если кодировка UTF8, а ваш текст не Latin1 (или обычный 7-битный ASCII), вам нужно проверить длину массива закодированных байтов, а не длину строки Java.

java