如何在Java中以i18n友好的方式将格式化的整数写入文件?

时间:2014-04-01 05:35:02

标签: java file internationalization streamwriter filewriter

我目前正在使用

        try {
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("open_sites_20,txt"), "UTF-8"));
            writer.write(String.format("%4d%4d%n", i, j));
            writer.close();
        } catch (IOException e) {
            System.err.print("error: " + e.toString() + "\n");
        };

其中i,j是整数。

FindBugs报告上述内容有以下不良做法

Reliance on default encoding
Found a call to a method which will perform a byte to String (or String to byte) conversion, and will assume that the default platform encoding is suitable. This will cause the application behaviour to vary between platforms. Use an alternative API and specify a charset name or Charset object explicitly.

有什么建议可以改进吗?

平台:IntelliJ IDEA 13.1.1 + FindBugs-IDEA 0.9.992。

1 个答案:

答案 0 :(得分:0)

在这种情况下,FindBugs似乎是错误的。请记住,它的规则并没有刻在石头上,因此有必要运用你自己的判断。

至于改善事物。您可以通过几种方法来改进此代码。首先,让我们处理字符编码。自Java 1.4起,OutputStreamWriter contains constructor具有以下签名:

OutputStreamWriter(OutputStream stream, Charset charEncoding)

最好使用它,而不是将编码名称作为字符串传递。为什么?从Java 7开始,您可以使用StandardCharsets枚举来创建Charset类实例。因此你可以写:

new OutputStreamWriter(new FileOutputStream("open_sites_20,txt"), StandardCharsets.UTF_8)

我不认为FindBugs会为此辩论。

我在这里看到的另一个问题是你关闭作家的方式。在某些情况下,不会调用此方法。处理它的最佳方法(如果您使用的是Java 7及更高版本)是使用try-with-resources并让Java关闭流/编写器:

try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
         new FileOutputStream("open_sites_20,txt"), StandardCharsets.UTF_8));) {
    writer.write(String.format("%4d%4d%n", i, j));
    // It always make sense to flush the stream before closing
    writer.flush();
} catch (IOException e) {
    System.err.print("error: " + e.toString() + "\n");
};

现在,您要做的就是将单个值写入文件。如果我是你,我会尽量避免创建流的所有开销,用编写器包装它等等。这很复杂。幸运的是,Java 7有一个非常棒的类可以帮助您将文本文件写入文本文件:Files 当您需要将某些内容写入文本文件时,该类有两种方法可以派上用场:

write(Path path, byte[] bytes, OpenOption... options)
write(Path path, Iterable<? extends CharSequence> lines, Charset cs, OpenOption... options)

第一个也可用于编写二进制文件。第二个可用于编写字符串集合(数组,列表,集合,...)。您的程序可以重写为:

try {
    Path outputPath = Paths.get("open_sites_20,txt");
    String nmbrStr = String.format("%4d%4d%n", i, j);
    byte[] outputBytes = nmbrStr.getBytes(StandardCharsets.UTF_8));
    Files.write(outputPath, outputBytes, StandardOpenOption.CREATE);
} catch (IOException ioe) {
    LOGGER.severe(ioe);
}

那就是它! 简单而优雅。我在这里用的是: