【问题标题】:Use Get-Content in powershell as java input get extra character在powershell中使用Get-Content作为java输入获取额外字符
【发布时间】:2019-04-04 14:35:19
【问题描述】:

我正在练习使用命令行在windows 10中运行java脚本。java脚本使用scanner(System.in)从文件中获取输入并打印它从文件中获取的字符串。powershell命令如下:

Get-Content source.txt | java test.TestPrint

source.txt文件内容如下:

:
a
2
!

TestPrint.java 文件如下:

package test;

import java.util.Scanner;

public class TestPrint {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner in = new Scanner(System.in);

        while(in.hasNextLine())
        {
            String str = in.nextLine();
            if(str.equals("q")) break;
            System.out.println( str );          
        }
    }

}

然后奇怪的事情发生了。结果是

?:
a
2
!

你看,它在第一行的乞求中添加了问号。然后当我将source.txt文件第一行的字符从“:”更改为“a”时,结果是

 a
a
2
!

它在第一行的乞求中添加了空格。

我测试了字符,发现规律:如果字符大于"?"在ASCII中,在ASCII中是63,那么它会添加空格,例如"A"(ASCII中的65)或@987654331 @(91 in ASCII).如果字符小于“?”,包括“?”本身,它会添加问号。

【问题讨论】:

  • PS:*source.txt* 是我想用粗体的时候,但是效果不好。没有语法错误。
  • 你的PS C:\> $OutputEncoding 是什么?为什么选择使用用户系统当前“默认”编码的scanner 构造函数?
  • 当你说“source.txt 是我想使用粗体的时候”你的意思是你只是想在问题中加粗 source.txt 但你是什么真正从命令行输入的是:Get-Content source.txt | java test.TestPrint
  • @CharlieWallace 是的,你是对的。这就是我的意思。我是个新手!我找到了编辑帖子的方法。而且似乎代码区域无法添加粗体格式。
  • @TomBlodget 抱歉,我无法发布$OutpurtEncoding 的全部结果,因为评论似乎无法使用代码块。我认为结果中的相关部分是:EncodingName : US-ASCIIWindowsCodePage : 1252

标签: java powershell


【解决方案1】:

这可能是 Unicode 问题(请参阅:Java Unicode problems)?即尝试指定要读取的类型:

Scanner in = new Scanner(System.in, "UTF-8");

编辑:

经过进一步研究,PowerShell 5.1 及更早版本,默认代码页为 Windows-1252。 PowerShell 6+ 和跨平台版本已切换到 UTF-8。因此(来自 cmets)您可能必须指定 Windows-1252 编码:

Scanner in = new Scanner(System.in, "Windows-1252");

要找出正在使用的编码,请在 PowerShell 中执行以下命令:

[System.Text.Encoding]::Default

您应该能够看到正在使用什么编码(对于我来说,在 PowerShell v 5.1 中是 Windows-1252,对于 PowerShell 6,它是 UTF-8)。

【讨论】:

  • 是的,这似乎是Unicode问题。如果我将编码更改为"UTF-8",那么无论第一行是什么字符,都会在第一行的乞求处添加问号。所以这是否意味着我应该像@Tom Blodget 所说的那样将编码更改为我系统的默认编码?
  • 是的,我会尝试@TomBloget 所说的,尝试“Windows-1252”作为编码,或者您的默认编码是什么。
  • @earwen 我已经编辑了答案以反映可能存在替代编码,具体取决于 PowerShell 的版本,以及如何找出您当前的编码方法。
  • 是的,我试过"Windows-1252"作为扫描仪构造函数中的编码。但结果是在第一行的开头添加了三个问号。我认为我的可能有问题eclipse 程序设置。我准备重新安装它,因为在我的另一台计算机上一切正常,具有相同的 java 程序和 txt 文件。
【解决方案2】:

没有文本,只有编码文本。

读取文本文件或流的每个程序都必须知道并使用与编写器相同的字符编码。

自适应默认字符编码是 70 年代和 80 年代问题(大约)的 90 年代解决方案。今天,通常最好避免使用默认值的构造函数和方法,并且在 PowerShell 中,在需要控制输入或输出的地方添加编码参数。

为防止数据丢失,您可以始终使用 Unicode 字符集。 UTF-8 是最常见的文件和流。 (PowerShell 和 Java 使用 UTF-16 作为文本数据类型。)

但是你需要从你所知道的文本文件的字符编码开始。如果您不知道此元数据,那就是数据丢失。

Unicode 规定,如果已知文件或流是 Unicode,它可以从称为 BOM 的元数据开始。 BOM 指示正在使用哪种特定的 Unicode 字符编码以及字节顺序是什么(对于代码单元长于一个字节的字符编码)。 [这条规定并没有解决我所看到的任何问题,并且会导致问题。]

(抽象级别的字符编码是代码点和代码单元之间的映射,因此与字节顺序无关。实际上,字符编码需要将代码单元序列化/反序列化到字节序列的附加步骤. 因此,有时使用或不使用 BOM 包含在编码的名称或描述中。BOM 也可能被称为签名。因此,“带有签名的 UTF-8。”)

作为元数据,BOM(如果存在)应在需要时使用,并且在将文本放入文本数据类型时始终丢弃。不幸的是,Java 的标准库并没有丢弃 BOM。您可以使用popular libraries 或十几行您自己的代码来执行此操作。

再次,从了解文本文件的字符编码开始,并将该元数据作为参数插入到处理中。

【讨论】:

  • 感谢您的帮助。我认为我的eclipse安装可能有问题,因为我在另一台计算机上尝试了相同的java程序和文件,一切都很好。
  • 这就是编写依赖于自适应默认值的代码的问题。您还必须知道文本文件的编码。如果您使用 Eclipse 创建它,您要么告诉它使用哪种编码,要么它为您选择一个。你应该为你想要的配置它。
  • 我通过更改 windows 10 系统的设置找到了解决方案。更改非 unicode 程序的语言设置,并取消选中 beta 框 i>.
  • 当然,它现在可以在您的计算机上运行。 (Windows 选择的措辞具有讽刺意味的是,PowerShell 和 Java 都本机使用 Unicode。不幸的是,总的来说,它们都拼命地坚持动态适应用户通常不知道或不关心的用户设置的旧想法。)
  • 哈哈。你是对的。即使我解决了问题,我也不能确定具体的原因是什么。我知道这对解决问题没有帮助,但我仍然要感谢你的耐心。它真的鼓励我继续我的编程
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 2012-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多