为什么在开始字符串和结束字符串之间删除会赢';在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 find
start
,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意味着您的流应该流动

  • 检查起始字符串
  • 写入数据
  • 标志为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; 
        }
    }
    

    下面是此应用程序的更新代码

    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;
    
          }