编写没有BOM的UTF-8

Maw*_*wia 6 java unicode byte-order-mark notepad++ utf-8

这段代码,

OutputStream out = new FileOutputStream(new File("C:/file/test.txt"));
out.write("A".getBytes());
Run Code Online (Sandbox Code Playgroud)

还有这个,

OutputStream out = new FileOutputStream(new File("C:/file/test.txt"));
out.write("A".getBytes(StandardCharsets.UTF_8));
Run Code Online (Sandbox Code Playgroud)

产生相同的结果(在我看来),这是没有BOM的UTF-8.但是,Notepad ++没有显示有关编码的任何信息.我希望notepad ++在这里显示为Encode in UTF-8 without BOM,但在"编码"菜单中没有选择编码.

现在,此代码使用BOM编码以UTF-8编写文件.

 OutputStream out = new FileOutputStream(new File("C:/file/test.txt"));
 byte[] bom = { (byte) 239, (byte) 187, (byte) 191 };
 out.write(bom);
 out.write("A".getBytes()); 
Run Code Online (Sandbox Code Playgroud)

Notepad ++也将编码类型显示为Encode in UTF-8.

问题:前两个代码有什么问题,假设用UTF-8编写文件没有BOM?我的Java代码是做正确的吗?如果是这样,notepad ++试图检测编码类型是否有问题?

记事本++只能猜测吗?

Joa*_*uer 15

使用UTF-8而不使用BOM 编写的"A"与使用ASCII或ISO-8859-*或任何其他ASCII兼容编码编写的"A" 完全相同.该文件包含一个十进制值为65的字节.

想一想:

  • "A".getBytes("UTF-8") 返回一个 new byte[] { 65 }
  • "A".getBytes("ISO-8859-1") 返回一个 new byte[] { 65 }
  • 您将这些调用的结果写入文件
  • 该文件的消费者应如何区分这两者?

没有在该文件中表明,UTF-8需要被用来解码.

尝试编写"Käsekuchen"或其他不能用ASCII编码的东西,看看Notepad ++是否正确猜测编码(因为这正是它的作用:它做了一个有根据的猜测,没有元数据告诉它使用哪种编码).

  • @Mawia:是的,确切地说."纯文本"没有元数据可以*告诉它编码(当然,除非有BOM),因此它使用一组启发式方法来猜测哪种编码最有可能.这并不是Notepad ++的错误:除了猜测之外你没什么可做的(你可以每次都询问用户,但这会很快烦人). (9认同)
  • @Mawia:我已经在答案中写道,它已经猜到了,我也在上面的评论中证实了这一点.你还在等第三次确认吗?;-)有些编码比其他编码有"更明显"的说法:例如,如果每隔一个字节为0(对于英语文本),通常可以检测到UTF-16,而UTF-8可以通过一些常见序列检测到(和其他永远不会出现的字节序列).可以通过对字节值的统计分析来"检测"其他编码.但所有这些只是猜测. (3认同)
  • Yummm,käsekuchen (2认同)