3
\$\begingroup\$

I am writing a storage for articles and I have decided to use GridFS from MongoDB. I have found and tested some code, but I am not sure that it is a best one. Could you advice me how to make it better?

private GridFS gridFs;

public String getPostContent(String name) {
    GridFSDBFile file = gridFs.findOne(name + ".html");
    if (file == null) {
        return "There is no text for this article.";
    }
    return getStringFromInputStream(file.getInputStream());
}

private static String getStringFromInputStream(InputStream is) {
    BufferedReader bufferedReader = null;
    StringBuilder builder = new StringBuilder();

    String line;
    try {
        bufferedReader = new BufferedReader(new InputStreamReader(is));
        while ((line = bufferedReader.readLine()) != null) {
            builder.append(System.getProperty("line.separator")).append(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (bufferedReader != null) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return builder.toString();
}

I will appreciate any suggestions even regarding chosen approach.

\$\endgroup\$
4
  • \$\begingroup\$ Are you on Java 8? \$\endgroup\$
    – h.j.k.
    Commented Feb 17, 2016 at 8:31
  • \$\begingroup\$ Also, are the files expected to be very big, or are they small enough (mostly) to fit in memory? \$\endgroup\$
    – h.j.k.
    Commented Feb 17, 2016 at 8:32
  • 1
    \$\begingroup\$ Java 7, but it would be great to have ideas for Java 8. \$\endgroup\$ Commented Feb 18, 2016 at 0:32
  • 1
    \$\begingroup\$ Files are no more than 1000 lines with 100 symbols. \$\endgroup\$ Commented Feb 18, 2016 at 0:33

1 Answer 1

2
\$\begingroup\$

Since you are already on Java 7, you can use try-with-resources on your BufferedReader for safe and efficient handling of the underlying I/O resource.

Also, if all you are interested in is to read a file contents as a single String, you can consider reading them into a String, and then there appears to be three simple ways using either Guava, Apache Commons IO or Spark (web framework) libraries:

// Guava
String content = new String(ByteStreams.toByteArray(is));
// Apache Commons IO
String content = IOUtils.toString(is, Charset.defaultCharset());
// Spark (web framework)
String content = IOUtils.toString(is);

Where applicable, it's recommended to specify the Charset explicitly, instead of relying on the default.

One difference with this approach is that newlines aren't normalized to System.getProperty("line.separator") like what you have done here. If this is crucial for your usage, then a slight refactoring can be:

private static String getStringFromInputStream(InputStream is) {
    try (InputStreamReader source = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(source)) {
        StringBuilder builder = new StringBuilder();
        // using for-loop for nicer scoping of 'line' variable
        for (String line = bufferedReader.readLine(); line != null;
                line = bufferedReader.readLine()) {
            if (builder.length() > 0) {
                builder.append(System.lineSeparator());
            }
            builder.append(line);
        }
        return builder.toString();
    } catch (IOException e) {
        // recommended to do something about it instead of just printStackTrace()
        // e.printStackTrace();
    }
}

Since you also suggest giving ideas about Java 8, you can use StringJoiner as a slightly better replacement - there is no need to handle the appending of System.lineSeparator() manually:

private static String getStringFromInputStream(InputStream is) {
    try (InputStreamReader source = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(source)) {
        StringJoiner builder = new StringJoiner(System.lineSeparator());
        for (String line = bufferedReader.readLine(); line != null;
                line = bufferedReader.readLine()) {
            joiner.add(line);
        }
        return joiner.toString();
    } catch (IOException e) {
        // do something
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Awesome! You gave me excellent idea to not write this code but to use already written. \$\endgroup\$ Commented Feb 18, 2016 at 18:15
  • \$\begingroup\$ Could you add a way from Spark framework: String content = spark.utils.IOUtils.toString(is) to your answer, please? \$\endgroup\$ Commented Feb 18, 2016 at 19:43
  • \$\begingroup\$ @yarix Updated. :) \$\endgroup\$
    – h.j.k.
    Commented Feb 19, 2016 at 0:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.