Search code examples
javabufferedreaderjava-iofilewriterprintwriter

The proper uses of a print writer and file writer


why should we use file writer and then wrap it with a print writer when we can directly use a print writer? and we use buffered readers so they can read large chunks of data at once but then to get the output printed we have to loop them into a while loop why don't we have a simpler way to get the output printed?


Solution

  • Let's first have a look at the javadoc for the main differences.

    FileWriter

    Convenience class for writing character files. The constructors of this class assume that the default character encoding ... FileWriter is meant for writing streams of characters.

    PrintWriter

    Prints formatted representations of objects to a text-output stream.

    Which means FileWriter focuses on character-wise output and you cannot define the character encoding. Whereas PrintWriter focuses on formatted text output and you can specify the character encoding.

    Find a small example as demonstraction

    // we need this as there is no convenient method to output a platform
    // specific line separator charcater(s)
    String newLine = System.getProperty("line.separator");
    try (FileWriter fw = new FileWriter("/tmp/fw.txt")) {
        fw.append('\u2126').append(newLine);
        fw.write(65);
        fw.append(newLine);
        fw.append(String.format("%10s: %s%n", "some", "value"));
        fw.append("some line").append(newLine);
    } catch (IOException ex) {
        System.err.println("something failed: " + ex.getMessage());
    }
    // the println() methods will append the right platform specific line separator
    // charcater(s)
    try (PrintWriter pw = new PrintWriter("/tmp/pw.txt", "UTF8")) {
        pw.append('\u2126');
        pw.println();
        pw.write(65);
        pw.println();
        pw.printf("%10s: %s%n", "some", "value");
        pw.println("some line");
    } catch (FileNotFoundException | UnsupportedEncodingException ex) {
        System.err.println(ex.getMessage());
    }
    

    If you run the snippet on a unicode aware machine (or run the code as java -Dfile.encoding=UTF-8 ...) the output will be

    fw.txt

    Ω
    A
          some: value
    some line
    

    pw.txt

    Ω
    A
          some: value
    some line
    

    For the above examples the code and the result look more or less the same. PrintWriter provide methods for formatted output, whereas for FileWriter you have to do the formatting before the output.

    But the big difference comes, when your environment is not unicode aware (or run the code as java -Dfile.encoding=ISO-8859-1 ...)

    fw.txt

    ?
    A
          some: value
    some line
    

    The unicode omega character cannot be printed with ISO8859-1 encoding.

    With the PrintWriter we defined the character encoding for the output. Which is independent from the default encoding of the environment.

    pw.txt

    Ω
    A
          some: value
    some line
    

    Back to your question. Wrapping a FileWriter into a PrintWriter. It is possible. But you loose the main benefit, the ability to choose the chracter encoding.

    try (PrintWriter pw = new PrintWriter(new FileWriter("/tmp/pwfw.txt"))) {
        pw.append('\u2126');
        pw.println();
    } catch (IOException ex) {
        System.err.println("something failed: " + ex.getMessage());
    }
    

    The file pwfw.txt will contain the unicode character omega only if the default encoding of the environment is unicode. So you would have the same limitation (for the encoding) like with FileWriter.

    If you have to use FileWriter or PrintWriter depends on your needs. I believe PrintWriter should to do it most of the time.