java 无法使用UTF8/ISO_8859_1编码文件

cvxl0en2  于 2023-05-27  发布在  Java
关注(0)|答案(2)|浏览(151)

我尝试使用以下方式将文件写入UTF8或ISO_8859_1:

BufferedWriter writer = null;
    try {
        writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(getFile("res")), StandardCharsets.ISO_8859_1));

        String line =" test encoding"+"\r\n";
        writer.write(line);
    } finally {
        try {
            if (writer != null)
                writer.close();
        } catch (Exception e) {
        }
    }

然后,我尝试使用以下方式显示文件编码:file -I,file --mime-encoding,但它总是显示我us-ascii。

file --mime-encoding res
res: us-ascii

file -I res
res: text/plain; charset=us-ascii

我做错了什么?
edit 1:我正在测试macos dunno是否改变了一些东西

jecbmhm3

jecbmhm31#

ISO-8859-1和UTF-8都是字符编码 *,旨在与旧的US-ASCII兼容,适用于所有标准的可打印字符,即代码0x 20到0x 7 E。这些字符包括所有小写和大写拉丁字母,没有重音,数字,空格和其他常见的标点符号。
当您简单地使用Java和任何其他工具(除了一些特定的字符编码)编写文件时,文件中没有任何内容表明它是如何编码的。
使用file命令的工具只是尝试根据文件的第一个字节进行猜测:它检查序列是否与预定的字符编码集有任何意义,当它找到似乎匹配的一个时报告它。
在您的测试中,您只使用那些标准的“英语”字符,因此任何与ascii兼容的编码都适合阅读文件。这就是为什么结果是us-ascii
如果开始使用不同的字符,例如[éÀÖî],您将得到不同的结果。
UTF-8、UTF-16和UTF-32允许用一个特殊的字节序列(称为byte-order mark (BOM))开始文件,该序列标识文件的编码。你必须先自己写。对于UTF-8,序列为0xEFBBBF
这将是:

try (OutputStream os = Files.newOutputStream(Paths.get("res"), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
  os.write(0xEF);
  os.write(0xBB);
  os.write(0xBF);
  try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os, StandardCharsets.UTF_8))) {
    bw.write("Testing with standard us-ascii chars!");
    bw.write(System.lineSeparator());
  }
}
x6h2sr28

x6h2sr282#

我目前正在调试这个问题,我想创建一个Ansi编码的txt文件,所以我只是通过使用以下代码片段解决了这个问题:

Charset charSet1 = StandardCharsets.ISO_8859_1;
BufferedWriter bw1 = new BufferedWriter(new OutputStreamWriter(fos, charSet1));
bw1.write(0xE1);
bw1.newLine();

你可以使用这种方法,但如果你可以实现它没有打印0xE1(这通知说,这是在Ansi格式编码代码)请让社会知道。
谢谢你。

相关问题