使用 Java 扫描器读取文件

Posted

技术标签:

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

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

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

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

【问题讨论】:

永远不要使用扫描仪!真的,你会遇到很多麻烦。 @Martijn Courteaux - 愿意提供哪怕是最轻微的提示,说明 Scanner 为何不好? 【参考方案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 字节的默认字节,而另一个它到达文件的末尾。无论如何,它工作正常!

【讨论】:

以上是关于使用 Java 扫描器读取文件的主要内容,如果未能解决你的问题,请参考以下文章

如何逐行读取文件并分隔行组成部分?

java读取大文本文件

如何使用扫描仪逐字符读取输入文件?

使用扫描仪读取输入文件时“正确”操作“光标”

java中怎么随机读取计算机中某个文件夹中的文件??谢谢

如何在 Java 中逐行读取文本文件并分隔每一行的内容?