p>这段代码,/ p>
pre> code> OutputStream out = new FileOutputStream(new File("C:/file/test.txt"));
out.write("A" .getBytes());
/代码> / PRE>
p>而这,/ p>
pre> code> OutputStream out = new FileOutputStream(new File("C:/file/test.txt"));
out.write("A" .getBytes(StandardCharsets.UTF_8));
/代码> / PRE>
p>产生相同的结果(在我看来),这是没有BOM的UTF-8。但是,strong> Notepad ++没有显示有关encoding / strong>的任何信息。我期待记事本++在这里显示为代码>在没有BOM /代码的情况下以UTF-8编码>,但是在"编码"菜单中没有选择编码./p>
p>现在,此代码使用BOM编码以./p>编写UTF-8文件
pre> code> 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());
/代码> / PRE>
p> Notepad ++还将编码类型显示为代码>以UTF-8 /代码编码> ./ p>
p> strong>问题:/ strong>前两个代码有什么问题,假设在没有BOM的情况下以UTF-8写入文件?我的Java代码是做正确的吗?如果是这样,notepad ++试图检测编码类型是否有问题?/ p>
p>记事本++只能猜测吗?/ p>
字母A可能是UTF-8,或ISO-646,或ISO-8859-1,或ISO-8859-2,或......没有办法让记事本++猜你正在考虑使用UTF-8。
为什么选择downvote? 哪里不对了?
对于downvoters:这个问题真的值得2个downvotes吗? 至少如果你我做/我> downvote发表评论为什么。
@prunge:评论downvotes是一个href ="http://meta.stackexchange.com/a/2373/40342">所需,但不是必需的/ a>。 那就是设计。 没有必要征求意见,因为那些投票的人已经决定不发表评论。
如果您不指定编码(第一个示例),JVM将使用操作系统默认编码(ANSI for Windows,UTF-8 for Linux)。
p>使用UTF-8而不使用BOM编写的"A"生成em> exact / em>与使用ASCII或ISO-8859- *或任何其他ASCII兼容编码编写的"A"相同的文件。该文件包含一个十进制值为65./p>的字节
p>这样想:/ p>
UL>
li> code>"A".getBytes("UTF-8")/ code>返回代码> new byte [] {65} / code> / li>
li> code>"A".getBytes("ISO-8859-1")/ code>返回代码> new byte [] {65} / code> / li>
li>您将这些调用的结果写入文件/ li>
li>文件的消费者应该如何区分这两个?/ li>
/ UL>
p>该文件中有em> nothing / em>表明需要使用UTF-8对其进行解码./p>
尝试编写"K?sekuchen"或其他不能用ASCII编码的东西,看看Notepad ++是否正确猜测编码(因为这正是它的作用:它做了一个有根据的猜测,没有元数据,他们告诉/ em>它使用哪种编码)./ p>
你的意思是记事本++只是在猜测吗?
@Mawia:是的,确切地说。"纯文本"没有元数据可以告诉/我>编码(当然,除非有BOM),因此它使用一组启发式方法来猜测哪种编码最有可能。这不是Notepad ++的错误:除了猜测之外你什么也做不了(你可以每次都询问用户,但这会很快烦人)。
好吧,我认为这是有道理的,因为当我用UTF-16编写它时,notepad ++显示为代码>在UCS-2 Big Endian / code>中编码。所以,记事本++只是猜测,对吧?
@Mawia:我已经在答案中写道,它已经猜到了,我也在上面的评论中证实了这一点。你还在等第三次确认吗? ;-)有些编码比其他编码有"更明显"的说法:例如,如果每隔一个字节为0(对于英语文本),通常可以检测到UTF-16,而UTF-8可以通过一些常见序列检测到(和其他永远不会出现的字节序列)。可以通过对字节值的统计分析来"检测"其他编码。但所有这些只是猜测。
Yummm,ksekuchen
我不知道我的答案是否正确,但让我在这里理解,/ p>
p>如上所述,如果你写"A"只是记事本++无法理解它是什么类型的编码,但是如果你想让notepad ++显示"没有BOM的UTF-8编码",如下图所示/ p>
p> img src ="https://i.stack.imgur.com/WbRXY.jpg"alt ="在此输入图像说明"> / p>
p>然后你必须欺骗Notepad ++,你可以使用下面的代码来完成它
img src ="https://i.stack.imgur.com/1qsWL.jpg"alt ="在此输入图像说明"> / p>
p>如果你想让notepad ++显示"以UTF-8编码",那么你应该从osw.write(" uFEFF")中删除子串部分,因为这是你试图插入的BOM字符。当您插入此字符时,文件编码类型将变为"编码为UTF-8",当您以编程方式删除时,它将变为"在没有BOM的UTF-8中编码",因为您已删除此BOM字符./p>
p>您需要做的另一个设置是更改Notepad ++的首选项,如下所示,
通过这样做,Notepad ++只能识别您想要的编码./p>
p> img src ="https://i.stack.imgur.com/TSkIS.jpg"alt ="在此处输入图像说明"> / p>
p>但是,如果您只是简单地写文本,它将被记事本++。/ p>视为"ANSI"
希望我的解释清楚,我的分析可以帮助某人。
然而,这种方法是一种解决方法,并没有建议,但在一个无助的情况下这是有效的。 / P>
p> strong>如果您不希望更改Notepad ++首选项,并且您仍希望编码为"在没有BOM的UTF-8中编码"/ strong>那么您必须执行以下操作,/ p>
p> img src ="https://i.stack.imgur.com/it6Kx.jpg"alt ="在此处输入图像说明"> / p>
我在我的博客中以更好的方式解释了同样的东西href ="http://learnings.joshikiran.com/2014/04/write-file-from-java-with-encoding-utf.html">这里/ A> / p>
更好地理解href ="http://learnings.joshikiran.com/2014/04/write-file-from-java-with-encoding-utf.html">这里/ a>
如此有用和清晰,