当前位置: 首页 > 面试题库 >

弯引号引起Java Scanner hasNextLine()为假-为什么?

谷德本
2023-03-14
问题内容

我遇到了一个问题,即使它可以与他人正常工作,也无法使java.util.Scanner读取保存在记事本中的文本文件。基本上,当它尝试读取问题文件时,它完全是空手的-
hasNextLine()为false,缓冲区为空,等等。我将其范围缩小到一个事实,即如果存在,它甚至不会读取第一行是文件中 任何地方
的卷曲报价。没有异常被抛出。请注意,同一文件上的BufferedReader没问题。

try {        
    int count = 0;
    Scanner scanner = new Scanner(new File("C:/myfile.txt"));

    while (scanner.hasNextLine()) {
        count++;
        scanner.nextLine();
    }

    scanner.close();
    System.out.print(count);

    count = 0;
    BufferedReader reader = new BufferedReader(new FileReader("C:/myfile.txt"));

    while (reader.readLine() != null) {
        count++;
    }

    reader.close();
    System.out.print(count);
}
catch(IOException e) {
    e.printStackTrace();
}

上面的代码读取一个只包含一个单引号的文件,然后输出“ 01”。在Google上进行的搜索使我尝试这样做:

Scanner scanner = new Scanner(new File("C:/myfile.txt"), "ISO-8859-1");

这使它起作用(即,它打印出“ 11”)。我还注意到,如果我进入记事本并执行另存为…,底部的默认编码为“ ANSI”。如果将其更改为“
UTF-8”并保存文件,则扫描仪(无编码)也可以使用。如果我告诉扫描仪“
UTF-8”,那么可以理解的是,仅当我另存为UTF-8时,它才能工作,但是即使我将其另存为“ ANSI”,“ ISO-8859-1”似乎也能使它工作。

因此,我知道它与文件编码有关,但是问题是我对文件编码一无所知。我对“
ISO-8859-1”的含义的了解非常模糊;为什么无论我如何保存文件,它都能正常工作?为什么BufferedReader不管如何工作?

编辑:

下面的链接/评论确实帮助我指出了正确的方向!我想我已经知道了。

首先,在记事本中:

  • “ ANSI”是CP1252
  • “ Unicode”是UTF-16LE
  • “ UTF-8”是…好吧,UTF-8

用十六进制表示的撇号表示为:

  • CP1252:92
  • UTF-16LE:1920年
  • UTF-8:E2 80 99

根据Charset.defaultCharset(),Java在我的系统上使用的默认编码为UTF-8。因此,当我将文件保存为UTF-8时,扫描仪便知道会发生什么。但是,当我将文件保存在CP1252中时,一旦它打到“
92”,它就会窒息,因为这不是用该编码表示字符的有效方法。只要文件中没有这样的字符,它就可以正常工作-“ hello
world”的十六进制在CP1252和UTF-8中恰好相同,并且不会引起问题。

UTF-8不适用于UTF-16文件,因为无论文件中包含什么字符,它都不知道如何处理字节顺序标记(“ FFFE”)。

另一方面,当我将扫描仪设置为CP1252或ISO-8859-1时,它的容忍度要高得多。请注意,它不一定 正确地
解释字符,但是没有什么可以阻止它识别文件中的行并循环浏览。

至于为什么扫描仪有问题,但FileReader /
BufferedReader没有问题,我想这是因为扫描仪需要标记文件,即。解释字符,以便可以识别空格和其他模式,因此在出现无法识别的内容时会窒息。读者不需要这样做。它需要识别的只是换行符。


问题答案:

如果在创建扫描仪时未指定编码,它将尝试根据字节顺序标记(BOM)(文件的前几个字节)来区分编码。如果没有,则默认为操作系统使用的默认值。由于您使用的是Windows,因此默认值为cp-1252。似乎记事本正在使用与ISO-12859类似但与cp-1252不同的ISO-8859-1保存文本文件。有关更多详细信息,请参见此链接:

http://www.i18nqa.com/debug/table-iso8859-1-vs-
windows-1252.html

当将其另存为UTF-8时,它可能会将UTF-8 BOM放置在文件的开头,并且扫描程序可以在其上进行拾取。

如果您想更多地了解BOM,请在Wikipedia中查找它-这篇文章很好。您也可以下载PSPad并以十六进制模式打开文本文件以查看各个字节。希望有帮助:)



 类似资料:
  • 问题内容: 这是适合此描述的命令行示例: 我已经尝试过'(不转义),URL编码(在另一端没有urldecoded!)和”(引号消失!),但没有成功。 问题答案: 如果您将“替换为Unicode编码的”(\ u0027),则可以使用: 奇怪,但是值得知道!

  • 问题内容: 因此,我有一个名为Save.php的文件。 它需要两件事:一个文件和新内容。 您可以通过发送类似的请求来使用它。 ..但当然是对网址进行编码。:)为了简化和可读性,我不做任何编码。 该文件有效,但不是内容。 ..我发现.. .. 当稍后通过XHR获取JSON文件时尝试使用时,当然会抛出错误。 要保存内容,我只用.. 我该怎么做才能消除反斜线? 问题答案: 关闭在php.ini关闭。

  • 问题内容: 该 逃生() 函数,已被废弃,取而代之 encodeURIComponent方法 ,但 encodeURIComponent方法 不编码单引号/单引号字符。我需要使用AJAX格式来避免姓氏(例如“ O’Neill”)中的撇号。他们为什么要消除他们试图改善的东西的能力? 编辑: 因此,这是一个代码示例,可以更彻底地说明问题。因此,您可以看到姓“ O’Neill”包含一个撇号,当在url中

  • 作为一个极简的示例,此代码并不恐慌 但是,直接用recover替换匿名函数会引起恐慌

  • 问题内容: 我想使用程序包执行Windows命令,但是Windows进行了一些奇怪的转义。 我有类似的东西: “SomeText” 但这会引发错误,因为Windows会将其转换为 有人知道为什么吗?如何使用exec程序包在Windows上执行? 谢谢! 问题答案: OK,这是一个比较复杂一点比你预期,但有 是 一个解决方案: 不幸的是,尽管在2011年添加了对此功能的支持,但它似乎尚未纳入文档中。

  • 问题内容: 据我所知,如果字体包含空格,则需要使用双引号或单引号,例如: 但是在Google字体上,我也看到了 有些人甚至这样使用它: 我觉得这很奇怪,因为以下方法也可以: 那么CSS中字体名称周围引号的正确用法是什么? 问题答案: 您可以随时把一个特定的字体系列名称在引号,双或单,所以,和是等价的。仅CSS定义的通用字体系列之类的名称必须不带引号。 与流行的看法相反,字体名称由空格分隔的名称组成