147. Writing formatted output directly to a file

Let's suppose that we have 10 numbers (integers and doubles) and we want them to be nicely formatted (have an indentation, alignment, and a number of decimals that sustain readability and usefulness) in a file.

In our first attempt, we wrote them to the file like so (no formatting was applied):

Path path = Paths.get("noformatter.txt");

try (BufferedWriter bw = Files.newBufferedWriter(path,
StandardCharsets.UTF_8, StandardOpenOption.CREATE,
StandardOpenOption.WRITE)) {

for (int i = 0; i < 10; i++) {
bw.write("| " + intValues[i] + " | " + doubleValues[i] + " | ");
bw.newLine();
}
}

The output of the preceding code is similar to what's shown on the left-hand side of the following diagram:

However, we want to obtain the result that's shown on the right-hand side of the preceding diagram. In order to solve this problem, we need to use the String.format() method. This method allows us to specify the format rules as a string that respects the following pattern:

%[flags][width][.precision]conversion-character

Now, let's take a look at what represents each component of this pattern:

  • [flags] is optional and consists of standard approaches for modifying the output. Often, they are used for formatting integers and floating-point numbers.
  • [width] is optional and sets the field width for our output (the minimum number of characters written to the output).
  • [.precision] is optional and specifies the number of digits of precision for floating-point values (or the length of a substring to extract from a String).
  • conversion-character is mandatory and tells us how the argument will be formatted. The most used conversion-characters are as follows:
    • s: Used for formatting strings
    • d: Used for formatting decimal integers
    • f: Used for formatting floating-point numbers
    • t: Used for formatting date/time values
As a line separator, we can use %n.

With this knowledge of formatting rules, we can obtain what we want as follows (%6s is used for the integers while %.3f is used for the doubles):

Path path = Paths.get("withformatter.txt");

try (BufferedWriter bw = Files.newBufferedWriter(path,
StandardCharsets.UTF_8, StandardOpenOption.CREATE,
StandardOpenOption.WRITE)) {

for (int i = 0; i<10; i++) {
bw.write(String.format("| %6s | %.3f |",
intValues[i], doubleValues[i]));
bw.newLine();
}
}

Another solution can be provided via the Formatter class. This class is dedicated to format strings and uses the same formatting rules as String.format(). It has a format() method, which we can use to rewrite the preceding snippet of code:

Path path = Paths.get("withformatter.txt");

try (Formatter output = new Formatter(path.toFile())) {

for (int i = 0; i < 10; i++) {
output.format("| %6s | %.3f |%n", intValues[i], doubleValues[i]);
}
}

How about formatting only the integer's numbers?

Well, we can obtain this by applying a DecimalFormat and a string formatter, as follows:

Path path = Paths.get("withformatter.txt");
DecimalFormat formatter = new DecimalFormat("###,### bytes");

try (Formatter output = new Formatter(path.toFile())) {

for (int i = 0; i < 10; i++) {
output.format("%12s%n", formatter.format(intValues[i]));
}
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.156.251