为什么在开始字符串和结束字符串之间删除会赢';在java中不能正常工作?
我有以下代表书籍的文件为什么在开始字符串和结束字符串之间删除会赢';在java中不能正常工作?,java,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=
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]
-------------------------
我已尝试使用此功能从文件中删除第二本书:
职能:
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]
-------------------------
此表达式的第二部分是删除“---------------------------”的原因(您从不打印“结束”行): 正因为如此
if(line.trim().equals(end)){
flag=true;
}
if (flag && !(line.trim().equals(end))){
pw.println(line);
pw.flush();
}
在第一个if
中,标志被设置为true,但是对于循环中的这个运行,行line.trim().equals(end)
也是true,因此当到达一行等于变量end
时,将永远不会访问第二个if。在这种情况下,它是------------
如果您的文件看起来总是一样的,您可以将循环更改为“when you findstart
,delete the next 5 line”(当您找到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();
}
第二个while将一直向下,直到找到结束,然后继续。从模式的角度来看问题-您要么处于复制模式,要么不处于复制模式。如果要复制,则除非找到开始模式,否则将输入复制到输出。如果确实找到开始模式,则切换到非复制模式 在非复制模式下,切换到复制模式时,只需查找结束模式 在代码术语中,这将成为
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;
}
}
}
您的第一个问题是这一行:
if (flag && !(line.trim().equals(end)))
由于您已经检查了当前行是否等于结束字符串,并将标志更改为true,因此对于结束字符串的每次出现,整个语句都将始终为true。这就是为什么输出中没有每一行。如果删除If语句中的第二部分,则意味着将其更改为:
If(flag){…}
您将实现结束字符串的每次出现都将在输出中。
这导致了代码的第二个问题:顺序。您使用一个标志作为输入到输出的阀门。当找到开始字符串时,您可以用您的标志发出关闭输出写入的信号。然后检查是否要发出打开输出写入的信号。只有这样,你才能根据旗帜进行写作。
您需要在此处更改顺序以获得有意义的数据流。
请考虑这两个州的BR>< 该标志为TRUE意味着您的流应该流动
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;
}
}
下面是此应用程序的更新代码
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,这将有助于从开始字符串到结束字符串排除内容。这是我能想到的最简单的解决方案:
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();
}
}
问题是您设置标志太早,因此没有打印出行 这是我提出的一个简单的解决方案,它将删除带有开始和结束字符串的所有内容,但只有在开始字符串匹配时才删除
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。这将有助于从开始字符串到结束字符串排除内容。将其记录在纸上,并检查条件-第一次迭代时,标志为true,行等于End,因此不会在文件中打印…您建议的代码不会删除一个'-------------------'好的,然后只需在内部循环后添加一个
continue
或一个新的readLine()
。不在循环中,在它之后!(将编辑答案)skip
与flag
的区别在哪里?Neil,它没有区别,skip可以被删除,而flag可以在它的位置使用。重点是何时启用和禁用该标志。当开始字符串匹配时应启用,而在处理结束字符串后应禁用。我的点是只需要重命名标志的点。你的一个布尔人是多余的。是的,我同意,这是我在前面的评论中说的
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();
}
}
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;
}