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
Если замена имеет разную длину:
- Читайте файл, пока не найдете строку, которую хотите заменить.
- Считайте в память часть после текста, который вы хотите заменить, полностью.
- Обрежьте файл в начале той части, которую вы хотите заменить.
- Написать замену.
- Запишите оставшуюся часть файла с шага 2.
Если замена имеет ту же длину:
- Читайте файл, пока не найдете строку, которую хотите заменить.
- Установите позицию файла в начало части, которую вы хотите заменить.
- Замена записи, перезапись части файла.
Это лучшее, что вы можете получить, учитывая ограничения вашего вопроса. Однако, по крайней мере, в рассматриваемом примере заменяется строка той же длины, поэтому второй способ должен сработать.
Также имейте в виду: строки Java представляют собой текст в Юникоде, в то время как текстовые файлы представляют собой байты с определенной кодировкой. Если кодировка UTF8, а ваш текст не Latin1 (или обычный 7-битный ASCII), вам нужно проверить длину массива закодированных байтов, а не длину строки Java.