使用 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
类,其中包含静态方法 readFileToString
和 readLines
用于文本,readFileToByteArray
用于二进制数据。
【讨论】:
【参考方案4】:您可以使用 Scanner 类,只需在打开扫描仪时指定一个字符集,即:
Scanner sc = new Scanner(file, "ISO-8859-1");
Java 使用指定的字符集将从文件中读取的字节转换为字符,如果没有给出 (source),这是默认字符集(来自底层操作系统)。我仍然不清楚为什么 Scanner 只读取 1024 字节的默认字节,而另一个它到达文件的末尾。无论如何,它工作正常!
【讨论】:
以上是关于使用 Java 扫描器读取文件的主要内容,如果未能解决你的问题,请参考以下文章