0

I have an problem with the DataInputStream, it doesn't read the file completly there are every so often (every ~33000 chars) 2-3 chars skipped. I am trying to parse the file (8 mb) as json and with those skipped chars in the string I can't parse the string as json.

public static String readTemplate(String templateName) throws IOException
{
    log.info("Opening Template");
    InputStream resStream = this.getClass().getResourceAsStream("/assets/"+SpellCraftMod.MODID+"/templates/"+templateName+".json"); // I need to open the file that way
    DataInputStream in = new DataInputStream(resStream);
    String temp = "";
    SpellCraftMod.log.info("Reading Data");
    int available = 0;
    while ((available = in.available()) > 0)
    {
        try
        {
            temp += in.readUTF();
        } catch (EOFException ignore) {}
        log.info("To GO: " + available);
    }
    log.info("Closing File");
    in.close();
    resStream.close();
    return temp;
}
user3412531
  • 27
  • 1
  • 6
  • are you using `writeUTF()` while writing in the file? why are you using `readUTF()` method? – Braj Aug 12 '14 at 19:49
  • @user3218114 no I converted the file to UTF-8 without BOM with Notepad++ – user3412531 Aug 12 '14 at 19:51
  • Your JSON parser should be able to read bytes from an Inpustream directly. Why do you read the resource as a String in the first place? – JB Nizet Aug 12 '14 at 19:53
  • @JBNizet I am using org.json and the constructor is new JSONObject(string json) – user3412531 Aug 12 '14 at 19:55
  • @user3412531: it also takes a JSONTokener as argument, and a JSONTokener takes an InputStream as argument: http://www.json.org/javadoc/org/json/JSONObject.html#JSONObject%28org.json.JSONTokener%29 – JB Nizet Aug 12 '14 at 20:00

1 Answers1

2

Use BufferedReader instead of DataInputStream. The former reads text from a character-input stream, buffering characters so as to provide for the efficient reading of characters, arrays, and lines.. I would prefer to use BufferedReader over Scanner for performance matters. Also, use a StringBuilder instead of concatenating Strings.

Here's a kickoff example:

BufferedReader br = new BufferedReader( new InputStreamReader(resStream, "UTF-8") );
StringBuilder sb = new StringBuilder();
String line;
while ( (line = br.readLine()) != null) {
    sb.append(line).append(System.lineSeparator());
}

If you work with Java 6 or prior, then you have to use System.getProperty("line.separator"); instead of System.lineSeparator()).

More info:

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • how do I create one from an InputStream? – user3412531 Aug 12 '14 at 19:53
  • 1
    @user3412531 using an InputStreamReader (be careful to specify the correct encoding). – JB Nizet Aug 12 '14 at 19:54
  • Works and its SUPER fast – user3412531 Aug 12 '14 at 20:00
  • @user3412531 that's probably for using these two classes `BufferedReader` and `StringBuilder`. – Luiggi Mendoza Aug 12 '14 at 20:01
  • java has `Files.readAllLines` respectively read the bytes and convert it then (apache commons has the missing function that reads directly into a single string.. annoying omission of the file is particularly large) since java 7 too. – Voo Aug 12 '14 at 21:42
  • @Voo I've checked the code of `Files#readAllLines` and uses `BufferedReader` behind the scenes and stores all the data inside a `List` but OP needs it concatenated as a single big String so using this approach will work better. – Luiggi Mendoza Aug 12 '14 at 21:46