【问题标题】:Reading a file using Java scanner使用 Java 扫描器读取文件
【发布时间】:2011-04-20 22:21:26
【问题描述】:

我试图理解的 java 文件中的一行如下。

return new Scanner(file).useDelimiter("\\Z").next();

根据 java.util.regex.Pattern 文档,该文件预计将返回“输入的结尾,但对于最终终止符,如果有的话”。但发生的情况是它只返回文件中的前 1024 个字符。这是正则表达式模式匹配器施加的限制吗?这可以克服吗?目前我正在使用文件阅读器。但我想知道这种行为的原因。

【问题讨论】:

  • 永远不要使用扫描仪!真的,你会遇到很多麻烦。
  • @Martijn Courteaux - 愿意提供哪怕是最轻微的提示,说明 Scanner 为何不好?

标签: java regex file-io java.util.scanner filereader


【解决方案1】:

我自己,我无法重现这个。但我想我可以弄清楚发生了什么。

在内部,扫描程序使用 1024 个字符的字符缓冲区。如果可能,扫描程序会默认读取您的可读 1024 个字符,然后应用该模式。

问题出在您的模式中...它将始终匹配输入的结尾,但这并不意味着您的输入流/数据的结尾。当 Java 将您的模式应用于缓冲数据时,它会尝试查找第一次出现的输入结尾。由于缓冲区中有 1024 个字符,匹配引擎将位置 1024 称为分隔符的第一个匹配项,并将其之前的所有内容作为第一个标记返回。

出于这个原因,我认为输入结束锚点不适用于扫描仪。毕竟,它可能是从无限流中读取的。

【讨论】:

  • 嗨,马克,我认为这是扫描仪无法工作的正确原因。我投票赞成答案。让它工作的方法是标记正确的方法。谢谢你的回答。
【解决方案2】:

尝试将file 对象包装在FileInputStream

【讨论】:

  • 您能否edit 解释为什么这会有所帮助,以及潜在的问题是什么?就目前而言,这只不过是一条评论。
【解决方案3】:

Scanner 旨在从文件中读取多个原语。它真的不打算读取整个文件。

如果您不想包含第三方库,则最好循环遍历 BufferedReader,该FileReader/InputStreamReader 用于文本,或者循环遍历 FileInputStream 用于二进制数据。

如果您可以使用第三方库,Apache commons-io 有一个 FileUtils 类,其中包含静态方法 readFileToStringreadLines 用于文本,readFileToByteArray 用于二进制数据。

【讨论】:

    【解决方案4】:

    您可以使用 Scanner 类,只需在打开扫描仪时指定一个字符集,即:

    Scanner sc = new Scanner(file, "ISO-8859-1");
    

    Java 使用指定的字符集将从文件中读取的字节转换为字符,如果没有给出 (source),这是默认字符集(来自底层操作系统)。我仍然不清楚为什么 Scanner 只读取 1024 字节的默认字节,而另一个它到达文件的末尾。无论如何,它工作正常!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      相关资源
      最近更新 更多