Почему исключение между начальной и конечной строками не будет работать должным образом в java?
У меня есть следующий файл, который представляет книги
Book: ISBN=3
title=english1
publishDate=1/12/2015
pageCount=200
authors=[12, 11, john]
-------------------------
Book: ISBN=5
title=english2
publishDate=1/12/2015
pageCount=200
authors=[12, 11, john2]
-------------------------
Book: ISBN=6
title=english3
publishDate=1/12/2015
pageCount=200
authors=[12, 11, john3]
-------------------------
Я попытался удалить вторую книгу из файла, используя эту функцию:
Funtion:
public static void removeLineFromFile(String file, String start, String end) {
try {
File inFile = new File(file);
//Construct the new file that will later be renamed to the original filename.
File tempFile = new File(inFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
String line = null;
Boolean flag=true;
//Read from the original file and write to the new
//unless content matches data to be removed.
while ((line = br.readLine()) != null) {
if (line.trim().equals(start)) {
flag=false;
}
if(line.trim().equals(end)){
flag=true;
}
if (flag && !(line.trim().equals(end))){
pw.println(line);
pw.flush();
}
}
pw.close();
br.close();
//Delete the original file
if (!inFile.delete()) {
System.out.println("Could not delete file");
return;
}
//Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile))
System.out.println("Could not rename file");
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
вызов функции:
public static void main(String[] args) {
removeLineFromFile("E:\\file.txt", "Book: ISBN=5","-------------------------")
}
книга была удалена, но другой раздел "-------------------------" также удален
`
Book: ISBN=3
title=english1
publishDate=1/12/2015
pageCount=200
authors=[12, 11, john]
Book: ISBN=6
title=english3
publishDate=1/12/2015
pageCount=200
authors=[12, 11, john3]
Что мне делать, чтобы получить следующий результат:
Book: ISBN=3
title=english1
publishDate=1/12/2015
pageCount=200
authors=[12, 11, john]
-------------------------
Book: ISBN=6
title=english3
publishDate=1/12/2015
pageCount=200
authors=[12, 11, john3]
-------------------------
Ответы
Ответ 1
Это самое простое решение, которое я мог бы придумать:
public static void removeLineFromFile(String file, String start, String end) {
try {
File inFile = new File(file);
//Construct the new file that will later be renamed to the original filename.
File tempFile = new File(inFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
String line = null;
Boolean flag=true;
//Read from the original file and write to the new
//unless content matches data to be removed.
while ((line = br.readLine()) != null) {
if (line.trim().equals(start)) {
flag=false;
}
if (flag){
pw.println(line);
pw.flush();
}
if(line.trim().equals(end)){
flag=true;
continue;
}
}
pw.close();
br.close();
//Delete the original file
if (!inFile.delete()) {
System.out.println("Could not delete file");
return;
}
//Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile))
System.out.println("Could not rename file");
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
Проблема заключалась в том, что вы устанавливали флаг слишком рано и, следовательно, не печатали строку.
Ответ 2
Ваша первая проблема связана с этой строкой:
if (flag && !(line.trim().equals(end)))
Так как вы уже проверили, соответствует ли текущая строка вашей конечной строке String и изменит флаг на true, весь этот оператор всегда будет истинным для каждого вхождения конца String. Вот почему каждая строка -------------------------
не находится на выходе.
Если вы удалите вторую часть в этом выражении if, это изменит ее на: if(flag){...}
, вы достигнете того, что каждое появление конца строки будет в выводе.
Это приводит к второй проблеме с вашим кодом: заказ. Вы используете флаг в качестве клапана для ввода на выход. Вы сигнализируете своим флагом, чтобы отключить запись на выходе, когда нашли начальную строку. Затем проверьте, хотите ли вы сигнализировать о вводе вывода. И только тогда вы будете писать в зависимости от флага.
Вам нужно изменить порядок здесь, чтобы получить значимый поток данных.
Рассмотрим два состояния
Флаг TRUE означает, что ваш поток должен течь
- Проверить начальную строку
- Запись данных
Флаг FALSE означает, что ваш поток НЕ должен течь
- Не записывать данные
- Проверить конец строки
Вы можете добиться желаемого поведения с этим циклом while.
while ((line = br.readLine()) != null) {
if (line.trim().equals(start)) {
flag=false;
}
if (flag){
pw.println(line);
pw.flush();
}
if(line.trim().equals(end)){
flag=true;
}
}
Ответ 3
Вторая часть этого выражения - это то, почему ваш "-------------------------" удаляется (вы никогда не печатаете строки "end" ):
(flag && !(line.trim().equals(end)))
Ответ 4
Из-за этого.
if(line.trim().equals(end)){
flag=true;
}
if (flag && !(line.trim().equals(end))){
pw.println(line);
pw.flush();
}
В первом if
флаг установлен true, но строка line.trim().equals(end)
также верна для этого прогона в цикле, поэтому вторая, если никогда не будет посещаться, когда линия будет равна переменной end
, В этом случае это -------------------
.
Если ваш файл выглядит всегда одинаковым, вы можете изменить цикл на "когда вы найдете start
, удалить следующие 5 строк", что на самом деле не эстетично, или вам нужно вложить новый цикл в первый if
.
Вложенный цикл может выглядеть так:
while ((line = br.readLine()) != null) {
if (line.trim().equals(start)) {
while (!(line = br.readLine()).equals(end));
line = br.readLine();
// or you just write:
// continue;
}
pw.println(line);
pw.flush();
}
Второй, пока он просто спустится, пока не найдет конец, и это продолжается.
Ответ 5
Посмотрите на проблему с точки зрения режимов - вы либо находитесь в режиме копирования, либо нет. Если вы копируете, то, если вы не найдете шаблон начала, вы скопируете вход на выход. Если вы найдете шаблон начала, вы перейдете в режим без копирования.
В режиме без копирования вы просто смотрите на шаблон конца при переключении в режим копирования.
В кодовых терминах это становится
Boolean copyMode=true;
while ((line = br.readLine()) != null) {
if(copyMode) {
// Check for signal to stop copying
if(line.trim().equals(start)) {
copyMode = false;
continue;
}
// Just copy to output file
pw.println(line);
} else {
// Check for signal to restart copying
if(line.trim().equals(end)) {
copyMode = true;
}
}
}
Ответ 6
Ниже приведен обновленный код для этого
public static void removeLineFromFile(String file, String start, String end) {
try {
File inFile = new File(file);
//Construct the new file that will later be renamed to the original filename.
File tempFile = new File(inFile.getAbsolutePath() + ".tmp");
BufferedReader br = new BufferedReader(new FileReader(file));
PrintWriter pw = new PrintWriter(new FileWriter(tempFile));
String line = null;
Boolean flag=false;
Boolean skip=false;
//Read from the original file and write to the new
//unless content matches data to be removed.
while ((line = br.readLine()) != null) {
if (flag || line.trim().equals(start)) {
flag=true;
skip =true;
}
if (!skip) {
pw.println(line);
pw.flush();
}
if(flag && line.trim().equals(end)){
flag=false;
skip=false;
}
}
pw.close();
br.close();
//Delete the original file
if (!inFile.delete()) {
System.out.println("Could not delete file");
return;
}
//Rename the new file to the filename the original file had.
if (!tempFile.renameTo(inFile))
System.out.println("Could not rename file");
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
}
Обратите внимание на введение нового флага skip. Это поможет исключить содержимое из строки "Пуск" в конец строки.
Ответ 7
Это простое решение, при котором я подошел, он удалит все вещи, начиная с начала и конца строк, но только после того, как начнется строка начала.
Boolean flag1=true;
Boolean flag2=true;
//Read from the original file and write to the new
//unless content matches data to be removed.
while ((line = br.readLine()) != null) {
if (flag1&&line.trim().equals(start)) {
flag1=false;
}
if(!flag1&&line.trim().equals(end)){
flag2 = false;
flag1=true;
}
if (flag1&&flag2){
pw.println(line);
pw.flush();
}
if(!flag2) flag2=true;
}
Обратите внимание на введение нового flag1 и flag2 вместо flag.This поможет в исключении содержимого из строки Start в End string.