当前位置: 首页 > 知识库问答 >
问题:

如何查找系统的字符集。如果标准输出被重定向,是否出错?

党博超
2023-03-14

查找系统的字符集。退出是一件棘手的事情。(请参阅Logback System.err输出使用错误编码,以了解Logback的讨论和含义。)下面是系统的内容。API文档中说。

“标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于主机环境或用户指定的显示输出或其他输出目标。从字符到字节的转换中使用的编码相当于控制台。charset()如果控制台存在,则为charset。默认字符集()否则。

在我的Windows 10命令提示符下,使用Java 17,Charset。defaultCharset()返回windows-1252,而系统返回。控制台()。charset()返回IBM437。如果创建一个新的OutputStreamWriter(System.out,System.console())。charset())并写入字符串,它会按预期生成字符串。但是如果我使用新的OutputStreamWriter(System.out,Charset.defaultCharset())并写入“é”,它会生成Θ!这就是为什么我必须使用新的OutputStreamWriter(System.out,System.console())。charset())。

有一个问题:正如Baeldung所解释的,如果标准输出被重定向(例如,<代码>…

final Charset systemOutCharset = System.console() != null
    ? System.console().charset() : Charset.defaultCharset();

但这里有一个巨大的问题:<代码>系统。err按相同的规则运行:如果有控制台,则系统。控制台()。charset()用作系统。错误charset,否则charset。defaultCharset()。

从字符到html" target="_blank">字节的转换中使用的编码相当于控制台。charset()如果控制台存在,则为charset。默认字符集()否则。

正如我们所见,如果我们重定向stdout,那么就没有Console。如果我们重定向stdout而不是stderr呢?在我的系统上,System.out将使用charsetWindows-1252编写(重定向),并且System.err仍将使用charsetIBM437打印到控制台。这似乎直接与它的API契约相矛盾,因为没有ConsoleSystem.err正在使用,而不是Charset.defaultCharset(),而是其他一些字符集(如果存在,Console.charset()会返回什么)。此外,不再有任何方法可以访问System.err的字符集,因为没有System.console(),因为stdout正在重定向!

如何发现用于系统的正确字符集。如果重定向标准输出,是否出错?为什么没有系统。在这种情况下,是否遵守其API合同?

我只能假设这是JavaAPI的疏忽,应该有一个System.getConsoleCharset()方法,无论System.console()是否存在,它都会返回正确的值。

这可能比您想象的更有意义。像Logback这样的日志系统(参见LOGBACK-1642)通常配置为将日志输出发送到stderr(参见例如https://unix.stackexchange.com/q/331611),并且日志包在未来的很多年里都不需要Java18(在下面的答案中提到),因为它们实现了必须与最低支持的Java版本一起工作的交叉功能。由于这个Java错误(而且它似乎确实是一个错误,并且带有API盲点),如果使用stderr,日志系统无法确定使用哪个字符集作为其输出,这可以说是最佳实践!

共有1个答案

微生宝
2023-03-14

Java 18正好满足您的需要:

[…]

public Charset charset()
返回此PrintStream实例中使用的字符集。

返回:
此PrintStream实例中使用的字符集
自:
18

不幸的是,这意味着只有早期Java版本才有黑客攻击-因为这些方法通常只是因为需要而添加的。

有了它,要使用的字符集很简单

System.err.charset()
 类似资料:
  • 问题内容: 在bash中,调用将在stdout上显示该命令的任何输出。 调用会将该命令的任何输出重定向到指定的文件(在本例中为“输出”)。 有没有一种方法可以将输出重定向到文件 并 在stdout上显示? 问题答案: 您想要的命令名为 : 例如,如果您只关心标准输出: 如果要包括stderr,请执行以下操作: 将通道2(stderr /标准错误)重定向到通道1(stdout /标准输出),以便将两

  • 问题内容: 是否可以在Python中临时重定向stdout / stderr(即在方法期间)? 编辑: 当前解决方案的问题(我最初记得但后来忘记了)是它们没有 重定向 ;相反,它们只是完全替换了流。因此,如果某个方法由于某种原因(例如,由于将流作为参数传递给某物)而具有该变量的 本地 副本,则该方法将无效。 有什么办法吗? 问题答案: 要解决某些函数可能已将流作为局部变量缓存的问题,因此替换全局变

  • 问题内容: 我正在使用以下代码启动流程构建器。我想知道如何将其输出重定向到字符串。 我尝试使用,但似乎没有用。 问题答案: 从阅读。您可以将输出附加到:

  • 问题内容: 我正在尝试从主机系统调用docker的mysqldump,以从golang保存mysql dump。它可以与主机mysqldump正常工作,但不能与docker的mysqldump一起工作。 } 我只有非空数据库的 空mysql dump 问题答案: 解决方案是: } 没有“> dbname.sql”

  • 问题内容: 我的基本程序从脚本GUI.py导入了它的GUI界面。 在我的GUI.py中: 但是它的作用是打开两个窗口,第一个窗口 (顶层 窗口 ) 按预期工作,第二个窗口 处于空闲状态 , 这是期望的,直到我单击某个按钮 ,该 按钮 在连续按下后打印数据,并且打印的数据应出现在第二个窗口的文本小部件中, 但是 不会发生,程序也没有响应,当我关闭“顶层”窗口时,会出现错误消息 “ TclError:

  • 我在raspberry pi上得到了一个启动时运行的python脚本(运行良好),我想将输出附加到现有的文本文件中。我在我的/etc/rc.local文件中得到了这段代码(我在cron中也尝试了同样的方法,但由于某种原因,它甚至没有启动脚本)。 不幸的是,无论我尝试什么,日志文件总是空的,除非我直接运行同一个命令并通过按ctrl c而不是ctrl z中止脚本。似乎脚本必须以正确的方式关闭,然后才能