无法在java中读取文件

时间:2012-05-11 18:27:15

标签: java

我在使用Java读取文件时遇到了一些麻烦。

文件的样子:

Answer 1:
1. This is an apple
2. Something
Answer 2:
1. This is a cool website 
2. I love banana
3. This is a table
4. Programming is fun
Answer 3. 
1. Hello World
.... 

我想要做的是将它们分成两个部分: 一个是答案号码;另一个是答案清单。

假设我有一个名为Answer的对象类: 答案编号的字符串 答案清单。

到目前为止,这是我在将代码放入对象类之前调试代码所做的工作。但我无法得到正确的结果

public void reader(String file) throws FileNotFoundException, IOException {
    FileReader fR = new FileReader(file);
    BufferedReader bR = new BufferedReader(fR);
    String line = null;

    int count = 0 ;
    String blockNum = "";
    String printState = "" ;
    while ((line = bR.readLine()) != null) {
        if(line.contains("Answer")){
            //System.out.println("Contain Answer statement: " + line);
            count++;
            blockNum = line; 
            printState = "";
        }
        else{
            //System.out.println("No Answer Statement: " + line);
            printState += line + " / " ;
        }

        System.out.println( count + " " + blockNum + "   " + printState );
    }

    // Close the input stream
    bR.close();
    fR.close();
}

我很确定在编码时我做了些蠢事。我不太清楚如何阅读它以便将它分开。

现在输出如下:

1 Answer 1:   
1 Answer 1:   1. This is an apple / 
1 Answer 1:   1. This is an apple / 2. Something / 
2 Answer 2:   
2 Answer 2:   1. This is a cool website  / 
2 Answer 2:   1. This is a cool website  / 2. I love banana / 
2 Answer 2:   1. This is a cool website  / 2. I love banana / 3. This is a table / 
2 Answer 2:   1. This is a cool website  / 2. I love banana / 3. This is a table / 4. Programming is fun / 
3 Answer 3.    
3 Answer 3.    1. Hello World / 

但我希望输出是这样的:

1 Answer 1:   1. This is an apple / 2. Something / 
2 Answer 2:   1. This is a cool website  / 2. I love banana / 3. This is a table / 4. Programming is fun /    
3 Answer 3.    1. Hello World / 

4 个答案:

答案 0 :(得分:4)

您正在为您阅读的每一行输入打印一行输出。尝试在检查答案的循环部分内移动println,以确保只打印每个答案/答案值一次。 E.g:

if(line.contains("Answer")) {
    if (printState != "") {
        System.out.println(count + " " + blockNum + "   " + printState);
    }
    ...
}

编辑:退出while循环时还需要打印,以确保打印最后一个答案/答案值集。

答案 1 :(得分:1)

一种解决方案使用printTime的标志作为布尔值。

boolean printTime = false;

...
   if(line.contains("Answer")) {

       if (printTime!= false) {
          System.out.println( count + " " + blockNum + "   " + printState );
          printTime=false;
       }
        ...
  }else{
        //System.out.println("No Answer Statement: " + line);
        printState += line + " / " ;
        printTime=true; // you have one answer 
  }
  ...    

在最后一段时间结束时添加一些额外的印刷品

通过这种方式,您可以在一行中为一个答案提供多个printState。

但正确的“java”处理方式是创建你的对象:

List<Answer> listOfAnswer = new LinkedList<Answer>();
Answer answer;
...
if(line.contains("Answer")){
            //System.out.println("Contain Answer statement: " + line);
            count++;

            answer = new Answer(line);
            listOfAnswer.add(answer)
        }
        else{
            answer.add(new Answer(line));
        }
}
...

并且仅在打印出来之后:)

System.out.println(listOfAnswer.toString());

更简单的解决方案是使用

Map<Integer, LinkedList<String>> answers = new LinkedHashMap<Integer, LinkedList<String>();

答案 2 :(得分:1)

参见工作示例:

public void reader(String file) throws FileNotFoundException,
        IOException {
    BufferedReader reader = new BufferedReader(new FileReader(file));
    String line = "";
    while (reader.ready()) {
        line = reader.readLine();
        if (!line.contains("Answer")) {
            System.out.print(line + " / ");
        } else {
            System.out.println();
            System.out.print(line + " ");
        }
    }
}

答案 3 :(得分:1)

主要的输出问题是你在行迭代循环中打印(同时)。

要解决此问题,您可以按照@Albion answered进行操作并更改while内的打印位置,但正如其答案中的编辑所述,存在缺陷,您将需要打印循环后的额外时间,以获得正确的结果。

还有另一个难点,就是根本不在循环内打印它,我认为这是你的正确方法。要做到这一点,你只需要使用StringBuilder而不是String!


我也发现了一些不必要的变量,并且使用if(line.contains("Answer"))方法也存在一个缺陷,即如果“Answer”字符串出现在其中一个选项文本中,它将得到一个真实而混乱您的结果,例如:

Answer 1:
1. This is an apple
2. Capitalizing Is The Answer!
3. Something

将输出:

1 Answer 1:  1. This is an apple / 
2 2. Capitalizing Is The Answer!  3. Something

在大多数情况下,找到动态模式的最佳方法(就像你的那样,因为它会改变数字,而在上一个答案中,':'也带有'.' )是使用(模式)匹配器!我使用了这个:if(line.matches("Answer \\d[\\:\\.]")),如果您还不习惯,请参阅Pattern Docs,因为String.matches()是处理文本时可能会使用的内容。


解释每一个变化都有点麻烦,代码很简单,你分析后就掌握了,所以我只想发布我的方法:

public static void StackAnswer(String file) throws FileNotFoundException, IOException{
    BufferedReader br = new BufferedReader(new FileReader(file));
    StringBuilder output = new StringBuilder();
    int count = 0;
    while(br.ready()){
        String line = br.readLine().trim();
        if(line.matches("Answer \\d[\\:\\.]")){
            count++;
            output.append(System.lineSeparator()).append(count).append(' ').append(line);
        } else {
            output.append(" / ").append(line);
        }
    }
    System.out.println(output.toString().trim());
    br.close();
}
祝你好运!