使用Java Scanner读取文件时出现奇怪的行为

9
所以,当我使用Scanner类读取文件内容时,遇到了一个有趣的问题。基本上,我正在尝试从目录中读取由解析应用程序生成的几个输出文件,以计算一些准确性指标。
基本上,我的代码只是遍历目录中的每个文件,并使用扫描仪打开它们以处理内容。由于某种原因,一些文件(均为UTF-8编码)无法被Scanner读取。即使这些文件不为空,scanner.hasNextLine()在第一次调用时也会返回false(我打开了调试器并观察了这一点)。我每次都直接使用File对象初始化扫描仪(文件对象已成功创建)。例如:
    File file = new File(pathName);
    ...
    Scanner scanner = new Scanner(file);

我尝试了几件事情,最终通过以下方式初始化扫描器来解决这个问题:

    Scanner scanner = new Scanner(new FileInputStream(file));

虽然我很高兴解决了问题,但我仍然好奇在此之前可能会发生什么导致问题。 有任何想法吗?非常感谢!


我正在拼凑一些东西,结果遇到了你的确切问题。FileInputStream来解救! - masher
2个回答

5
根据Java 6u23中Scanner.java源代码,换行符被检测到。
private static final String LINE_SEPARATOR_PATTERN = 
                                       "\r\n|[\n\r???]";
private static final String LINE_PATTERN = ".*("+LINE_SEPARATOR_PATTERN+")|.+$";

所以你可以检查是否能将以下正则表达式与未读取的文件内容匹配。

.*(\r\n|[\n\r???])|.+$

另外,我会检查是否有异常被触发。

更新: 这让我很好奇,我寻找了答案。似乎你的问题已经在这里得到了解答: Java Scanner(File) misbehaving, but Scanner(FIleInputStream) always works with the same file

总结一下,这是关于超出ASCII范围的字符,在使用文件或文件输入流初始化Scanner时表现不同的问题。


没有引发任何异常,我已经将代码放在try catch块中。我查看了一下一直出问题的文件-每个文件都是由一个应用程序生成的,并且是以标准机器可读格式呈现的。这个文件夹里有100个文件,其中5个文件导致了这个问题。因为生成文件的应用程序实际上是以标准方式构建它们的,所以我希望行分隔符正常工作。我会确保这些文件中存在regexp。 - shaunvxc
然而,奇怪的是,当我使用FileInputStream来初始化扫描器时,而不仅仅是文件时,所有的内容都能够正常地被读取并且没有任何问题。 - shaunvxc
我曾经遇到过完全相同的问题。我想补充一下,你提到的正则表达式搜索并不是我的解决方案的一部分。问题在于从Web浏览器粘贴的文本包含一些超出范围的字符,这导致Scanner.hasNext()和Scanner.next()无法工作。使用FileInputStream解决了这个问题。 - Einar Sundgren

0
我会尝试检查您是否在读取文件后始终关闭扫描器。此外,您是只调用hasNextLine()和nextLine()方法,还是在该扫描器上调用了其他的nextXXX()方法?

对不起,我应该在我的问题中包含那个 - 是的,我在每个文件之后关闭了扫描器,并且我只调用了 hasNextLine() 和 nextLine()。对于引起问题的特定文件,第一次调用 hasNextLine() 返回 false。 - shaunvxc
你尝试过在读取那些“奇怪”的文件时调试Scanner吗? - Jan Krakora
是的,我确实这样做了,当我查看Scanner对象时,它的缓冲区完全为空。 - shaunvxc

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