0

I just made a very simple parser that gets input from a file and outputs to a file.

It does a line-by-line parsing of the file you give it and iterates the same function for all lines of the file and then it redirects the whole string to another file.

I give the parseLine function a JsonObjectBuilder so that it can keep on adding json-like structures to the output string (it's a normal text to json parser btw).

parseFile function

private String parseFile(String file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader (file));
    JsonObjectBuilder jsonBuilder = Json.createObjectBuilder();

    String line;
    try{
      while((line = reader.readLine()) != null){
        parseLine(line, jsonBuilder);
      }
    } finally {
      reader.close();
    }
    return jsonBuilder.build().toString();
  }

Parser class

public Parser(String file) throws IOException {
    PrintWriter out = new PrintWriter(System.getProperty("user.dir") + "/parser/src/main/resources/logFormatted.log");
    System.out.println("Initiated Parser class!");
    out.println(parseFile(file));
  }

parseLine function

private JsonObjectBuilder parseLine(String line, JsonObjectBuilder jsonBuilder){
    String timestamp = null;
    String eventCode = null;
    String payload = null;

    String finalString = null;
    try {
        timestamp = line.substring(0, 23);
        eventCode = line.substring(24, 28);
        payload = line.substring(29, line.length());

        jsonBuilder.add(timestamp, Json.createObjectBuilder()
                      .add("eventCode", eventCode)
                      .add("payload", payload)
                    );
    } catch (Exception ex) {
      System.out.println("ERROR: " + ex);
    }
    return jsonBuilder;
  }

Main

public static void main( String[] args ) throws IOException{
        Parser parser = new Parser(System.getProperty("user.dir") + "/parser/src/main/resources/newFormatLog.log");
    }

The problem with this code is that when it's executed it parses like it's supposed to but doesn't parse the whole file. Right now I'm giving it a ~4550 lines file but it does output a ~4400 line one.

I really don't know why and I'm starting to think the string is too big to handle or something. Maybe I need to output the lines immediatly to the file rather than doing a final big wite. All help is very appreciated!

Eugenio
  • 1,013
  • 3
  • 13
  • 33
  • 2
    If you were running into some kind of limit, I would expect Java to throw an exception - but you did not mention that. This leads me to believe that the program is working as it thinks it should :-p. It's probably a bad idea to accumulate all the data in the jsonBuilder, then output a big long string at the end - better to write it one line at a time, as you read them? – moilejter Oct 23 '18 at 08:07
  • @moilejter I thought the same but beeing quite new to Java I don't really know if I was right. Anyway the problem if I do parse a line and then `.build().toString()` is that it creates a lot of JSON objects line-by-line but I want to have a single JSON object for the whole file. – Eugenio Oct 23 '18 at 08:09
  • 1
    @ThomasWeller Sorry if I wasn't clear enought but I am trying to parse **from** a text file **to** a JSON file. The input is a file where all lines are simple statements and the output should be a single JSON file with the correct syntax. – Eugenio Oct 23 '18 at 08:11
  • 1
    Could you provide a [mcve], please? – Thomas Weller Oct 23 '18 at 08:12
  • @ThomasWeller I added the `parseLine` function. Tell me if you need more info and if so which one. Thanks for the suggestion. – Eugenio Oct 23 '18 at 08:15
  • 1
    Possible duplicate of [PrintWriter not printing out complete string](https://stackoverflow.com/questions/13806733/printwriter-not-printing-out-complete-string) – Eugenio Oct 23 '18 at 08:35

1 Answers1

0

Found out the problem. It was really dumb.

public Parser(String file) throws IOException {
    PrintWriter out = new PrintWriter(System.getProperty("user.dir") + "...");
    System.out.println("Initiated Parser class!");
    
    out.println(parseFile(file));
  }

In this constructor I was not closing the PrintWriter. Just added out.close(); and everything worked as expected.

public Parser(String file) throws IOException {
    try (PrintWriter out = new PrintWriter(System.getProperty("user.dir") + "...")) {

        System.out.println("Initiated Parser class!");
        out.println(parseFile(file));

     }
  }

You can refer to this other question as reference.

EDIT: Added try(PrintWriter out = ...) as suggested in the comments

Community
  • 1
  • 1
Eugenio
  • 1,013
  • 3
  • 13
  • 33
  • 1
    Or even better: `try(PrintWriter out = new PrintWriter(System.getProperty("user.dir") + "...")) { ... }` - [Read about it](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html). – LuCio Oct 23 '18 at 10:26
  • @LuCio Yeah, I ended up using that exact syntax for my code, it works very well since you can use the `finally` to do something at the end of the whole execution process. – Eugenio Oct 23 '18 at 10:38
  • But you realized you don't need to call `out.close` in the `finally` block? – LuCio Oct 23 '18 at 10:41
  • @LuCio Yeah you are right, I was just reading the docs :D. Thanks a lot! – Eugenio Oct 23 '18 at 10:43
  • Good to know, you got it. – LuCio Oct 23 '18 at 10:44