LogBack中LayoutWrappingEncoder的默认字符集是什么?

13

看起来你是碰巧得到了这个。我查看了源代码,没有找到任何调用“setCharset”的类在PatternLayoutEncoder中。文档使用“用户选择的字符集编码”来描述这个很好的回答中已经说明了。 - vanOekel
但是这个“偶然”是如何工作的呢?我在Windows机器上——它从哪里获取UTF-8呢?它必须来自某个地方。 - Garret Wilson
1
默认字符集(通过LayoutWrappingEncoder中的getBytes()使用)有点复杂,但并非神秘。这些链接可能有助于确定UTF-8来自何处? - vanOekel
1
啊,现在我们有了进展——你提到LogBack使用getBytes()的值,这意味着使用了Charset.defaultCharset的值。而奇怪的是……在我的Windows系统上,这返回UTF-8!这很令人惊讶,因为我一直以为InputStreamReader在Windows上默认不是UTF-8(例如Windows-1252)……但是不,它也返回“UTF8”!也许我的Eclipse+Maven设置做了一些奇怪的事情,或者Java 8改变了默认设置。无论如何,vanOekel,你想提供一个答案来获得赏金吗? - Garret Wilson
在Eclipse中,您可以在工作区设置中覆盖文件编码。我猜您已经将其设置为UTF-8了。此外,在运行配置文件中,您也可以更改编码:因为您已将项目/环境设置为UTF-8,所以在Eclipse中您将获得UTF-8。 - andygavin
我在下面添加了一个部分,解释了关于Eclipse的情况,我认为这是对你的问题的完整回答。 - andygavin
2个回答

20

Logback字符编码

你可以在PatternLayoutEncoder的定义中使用<charset>,因为它是LayoutWrappingEncoder的子类,后者提供了setCharset方法。文档中的某个片段指出了这一点,但没有给出示例xml配置。关于LayoutWrappingEncoder,这里已经给出了答案:[Logback-user]: 如何使用UTF-8

因此,如果您通过代码进行配置,可以调用setCharset方法,并将其设置为UTF-8。或者,如果您通过xml进行配置,则如下:

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <charset>UTF-8</charset>            
        <outputPatternAsHeader>true</outputPatternAsHeader>
        <pattern>[%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>

默认文件编码

Logback文档中指出使用默认字符编码是正确的。在Windows上,默认字符集通常不是UTF-8(例如我的是windows-1252)。正确的做法是像上面那样配置logback为UTF-8。即使logback从某个地方选择了UTF-8,或者file.encoding被您设置了,也不能保证这将来会发生。

顺便提一下,Sun曾经关于file.encoding说过,在Oracle VM上设置它:

"file.encoding"属性不是J2SE平台规范所必需的;它是Sun实现的内部细节,不应由用户代码检查或修改。它也旨在为只读;从技术上讲,在命令行或任何其他时间对该属性设置任意值都是不可能的。

Eclipse和Maven

如果您正在从Eclipse运行maven,并且已经在环境/项目或运行配置(对我来说是公共选项卡)中将其设置为UTF-8,则Eclipse将通过设置file.encoding来安排新的JVM具有UTF-8编码。请参阅:Eclipse的编码文档


4
系统的默认字符集由Java决定并在系统属性file.encoding中设置,但也可以在JVM启动时指定该属性(更多信息请参见此答案)。 Eclipse、Netbeans、Maven等可以使用此系统属性将默认字符集设置为UTF-8,这可能就是为什么输出是UTF-8,即使您没有指定它。
为了消除偶然性,请按此答案所示指定日志记录的字符集。 Logback的源代码显示了如何使用字符集将字符串转换为字节以写入文件convertToBytes方法中(有关字符串到字节的更多详细信息请参见此答案)。
在Unix上,file.encoding的值使用环境变量确定(例如通过LANG=en_US.UTF-8来解释,如此处所述,但其他环境变量也可能会涉及)。
在Windows上,使用命令chcp显示默认代码页。代码页编号与此列表中显示的字符集对应。例如,代码页65001对应于UTF-8。使用命令systeminfo | findstr Locale显示默认区域设置。
简而言之:一旦您的软件离开开发环境,您就不能假设任何特定的默认字符集。因此,请始终指定字符集。

1
两个提供的答案都很好。在选择赏金时,我必须考虑到 andygavin 先提供了一个答案;他提供了实际的代码来解决我的问题,而不是一个链接;并且他第一个指出我的 Eclipse+Maven 设置可能会导致我的默认字符集为 UTF-8。感谢您的反馈和关于 getBytes() 的注释是有帮助的。 - Garret Wilson
3
@GarretWilson 那听起来很公平。而且,我在这过程中也学到了一些东西,那总是不错的。 - vanOekel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接