4

I am writing a class that will read lines from a log file when it is updated.

I am using Apache VFS2 to get a method called when a file is updated. My main issue is I don't want to read the line from the file if the line is not complete yet, as in it does have a "\n" or "\r" line separator type character at the end. I think i have looked at all the Java libraries i can to read lines but they all discard the EOF and line termination information so I don't think I can use them.

Instead I am looking at reading it in byte by byte and then checking the result to then discard all stuff that comes after the last line separator. I was wondering what you folks thoughts on the best method for doing this is.

So for example:

2013-Jul-01_14:07:17.875 - Connection to Message Bus is reestablished<LF>
2013-Jul-01_14:07:17.875 - Connection to Message Bus is reestablished<LF>
2013-Jul-01_14:15:08.205 - No connection to Message Bus - reestablish before we can publish<LF>
2013-Jul-01_14:15:08.205 - NOT A REAL LINE PLEASE DONT READ

I want to read in the first 3 but not the fourth as it doesn't have a line feed or carriage return character ().

I have looked at Apache commons-io Tailer stuff but I cant tell if that will give me "incomplete" lines (and I realize I will have to ditch the VFS2 stuff to use it).

So psudo-code:

private void ingestFileObject(FileObject file) {
  BufferedInputStream bs = new BufferedInputStream(file.getContent().getInputStream());

  StringBuilder result = new StringBuilder();

  while (bs.available() > 0) {
     result.append((char) bs.read());
  }
  bs.close();

  String resultString = result.toString();
  //determine what part of resultString is after last carriage return/line seperate (using regex [\\r\\n]+?
  //remove the offending part of String.
  }

Or any other solutions completely ignoring my psudo-code are welcome at this point too...

Thanks

Raedwald
  • 46,613
  • 43
  • 151
  • 237
astropcr
  • 177
  • 2
  • 10
  • Not sure I understood the question that well. Since you know you have read the line, you can append a new line to the already read content? Does that change semantics? – Jayan Jul 16 '13 at 04:44
  • 1
    possible duplicate of [Carriage return and new line with Java and readLine()](http://stackoverflow.com/questions/4758525/carriage-return-and-new-line-with-java-and-readline) – Jayan Jul 16 '13 at 04:51
  • Why? Log files are for logging, and are intended to be read by humans. Use a database. – user207421 Jul 16 '13 at 10:34
  • Well we are trying to status a legacy system so parsing their log files is the best we got. I agree it is not ideal. Simillar to the carriage return question. Thanks. – astropcr Jul 16 '13 at 14:24

2 Answers2

1

Is using Scanner help you?

        Scanner scanner = new Scanner(file);

        //block till there is some thing with a new line
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            //do processing.
        }
Jayan
  • 18,003
  • 15
  • 89
  • 143
  • 1
    Unfortunately same issue where I don't know if the line I get back was terminated by EOF or carriage return and I need to be able to tell the difference. Thanks though. – astropcr Jul 16 '13 at 14:26
1

This is what I ended up doing:

 BufferedReader bufReader = new BufferedReader(new InputStreamReader(file.getContent().getInputStream()));
 StringBuilder result = new StringBuilder();
 int readInInt = -1;
 String charsSinceLastLineSep = "";

 if (bufReader.ready()) {
     while (-1 != (readInInt = bufReader.read())) {
        char readInChar = (char) readInInt;

        // if new line reset line buffer, otherwise add to buffer
        if (readInChar == '\n' || readInChar == '\r') {
           charsSinceLastLineSep = "";
        } else {
           charsSinceLastLineSep += readInChar;
        }

        result.append(readInChar);
     }
     bufReader.close();

     // remove all characters added since last Carriage Return or NewLine was found indicating
     // that line was not a complete log line
     String resultString = (result.subSequence(0, (result.length() - charsSinceLastLineSep.length())).toString());
astropcr
  • 177
  • 2
  • 10