BufferedReader readLine()问题:检测文件结束和空返回行

时间:2012-03-29 09:44:11

标签: java

我希望我的程序在最后一行文本末尾找到文件末尾(EOF)时执行某些操作,而当EOF位于最后一行文本后的空行时则需要执行其他操作。不幸的是,BufferedReader似乎认为两种情况都相同。

例如,这是我的代码,用于读取文件末尾的行:

FileReader fr = new FileReader("file.txt");
BufferedReader br = new BufferedReader(fr);
String line;

while((line = br.readLine()) != null) {
    if (line.equals("")) {
        System.out.println("Found an empty line at end of file.");
    }
}

如果file.txt包含此内容,则不会打印:

line of text 1
another line 2//cursor

这不会打印:

line of text 1
another line 2
//cursor

然而,这将:

line of text 1
another line 2

//cursor

我可以使用哪些读者来区分前两种情况?

6 个答案:

答案 0 :(得分:4)

您必须使用read而不是readLine并自行处理行尾检测。 readLine认为\n\r和EOF都是行终止符,并且在返回的内容中不包含终止符,因此您无法根据返回的内容进行区分字符串。

答案 1 :(得分:3)

您可以使用BufferedReader.read(char[] cbuf, int off, int len)方法。当到达文件末尾时,返回值-1,您可以检查最后一个缓冲区读取是否以行分隔符结束。

不可否认,代码会更复杂,因为它必须从read char[]缓冲区管理行的构造。

答案 2 :(得分:0)

public ArrayList<String> readFile(String inputFilename) throws IOException {
  BufferedReader br = new BufferedReader(new FileReader(inputFilename));

  ArrayList<String> lines = new ArrayList<>();
  String currentLine = "";

  int currentCharacter = br.read();
  int lastCharacter = -1;

  // Loop through each character read.
  while (currentCharacter != -1) {
    // Skip carriage returns.
    if (currentCharacter != '\r') {
      // Add the currentLine at each line feed and then reset currentLine.
      if (currentCharacter == '\n') {
        lines.add(currentLine);
        currentLine = "";
      } else {
        // Add each non-line-separating character to the currentLine.
        currentLine += (char) currentCharacter;
      }
    }

    // Keep track of the last read character and continue reading the next
    // character.
    lastCharacter = currentCharacter;
    currentCharacter = br.read();
  }

  br.close();

  // If the currentLine is not empty, add it to the end of the ArrayList.
  if (!currentLine.isEmpty()) {
    lines.add(currentLine);
  }

  // If the last read character was a line feed, add another String to the end
  // of the ArrayList.
  if (lastCharacter == '\n') {
    lines.add("");
  }

  return lines;
}

答案 3 :(得分:0)

我尝试从BufferedReader读取,该BufferedReader从套接字输入流接收其输入。 一切正常,直到最后一行为止,readLine()只是挂起,因为浏览器不会在发布数据上发送换行符终止符。

这是我的解决方案,能够读取直到输入流的结尾。

public String getLine(BufferedReader in) 
{
    StringBuilder builder = new StringBuilder();
    try {       
        while(in.ready()) { 
            char input = (char)in.read();
            /**
              * This method only matches on " \r\n" as a new line indicator.
              * change as needed for your own line terminators
              */
            if(input == '\r') {
                /** If we can read more, read one more character
                  * If that's a newline, we break and return.
                  * if not, we add the carriage return and let the 
                  *    normal program flow handle the read character
                  */
                if(in.ready()) {
                    input = (char)in.read();
                    if(input == '\n') {
                        break;
                    }
                    else {
                        builder.append('\r');
                    }
                }
            }
            builder.append(input);
        }       
    }
    catch(IOException ex) {
        System.out.println(ex.getMessage());
    }
    return builder.toString();
}

答案 4 :(得分:0)

您可以使用@hmjd 的解决方案或任何其他可以逐字节读取的阅读器。

如果你想坚持逐行阅读,你可以使用这个。

    boolean EOF = (currentLine = bufferedReader.readLine()) == null;
    while(!EOF){
        // do things that will happen no matter it is EOF or not
        EOF = (currentLine = bufferedReader.readLine()) == null;
        if(!EOF){
            // do things that will happen no matter it is not EOF
        }else{
            // do things that will happen no matter it is EOF
        }
    }
}

答案 5 :(得分:-1)

为什么不使用

if (line.length()==0) {
    System.out.println("Found an empty line.");
}

注意:这将检测文件中任何位置的空行,而不仅仅是EOF。