gpt4 book ai didi

java - 在不阅读完整文件的情况下估计文件的字数

转载 作者:搜寻专家 更新时间:2023-10-31 08:21:26 25 4
gpt4 key购买 nike

我有一个程序可以处理非常大的文件。现在我需要显示一个进度条来显示处理的进度。该程序在单词级别上工作,一次读取一行,将其拆分为单词并一个接一个地处理单词。因此,当程序运行时,它知道处理的单词数。如果它以某种方式事先知道文件的字数,则可以轻松计算进度。

问题是,我正在处理的文件可能非常大,因此处理文件两次不是一个好主意,一次是获取总字数,然后是运行实际处理代码。

所以我正在尝试编写一个代码,它可以通过读取文件的一小部分来估计文件的字数。这是我想出的(在 Clojure 中):

(defn estimated-word-count [file]
(let [^java.io.File file (as-file file)
^java.io.Reader rdr (reader file)
buffer (char-array 1000)
chars-read (.read rdr buffer 0 1000)]
(.close rdr)
(if (= chars-read -1)
0
(* 0.001 (.length file)
(-> (String. buffer 0 chars-read) tokenize-line count)))))

此代码从文件中读取前 1000 个字符,从中创建一个字符串,将其标记化以获取单词,计算单词数,然后通过将其乘以文件长度并除以它来估计文件的单词数1000。

当我在包含英文文本的文件上运行此代码时,我几乎得到了正确的字数统计。但是,当我在包含印地文文本(以 UTF-8 编码)的文件上运行此命令时,它返回的字数几乎是实际字数的两倍。

我知道这个问题是因为编码。那么有什么办法可以解决吗?

解决方案

作为suggested by Frank , 我确定前 10000 个字符的字节数和用它来估计文件的字数。

(defn chars-per-byte [^String s]
(/ (count s) ^Integer (count (.getBytes s "UTF-8"))))

(defn estimate-file-word-count [file]
(let [file (as-file file)
rdr (reader file)
buffer (char-array 10000)
chars-read (.read rdr buffer 0 10000)]
(.close rdr)
(if (= chars-read -1)
0
(let [s (String. buffer 0 chars-read)]
(* (/ 1.0 chars-read) (.length file) (chars-per-byte s)
(-> s tokenize-line count))))))

请注意,这里假定采用 UTF-8 编码。此外,我决定读取前 10000 个字符,因为它给出了更好的估计。

最佳答案

为什么不只根据处理的字节数而不是字数来制作进度条。您预先知道大小,然后主要的困难就是在处理它们时获取每个字的字节数或每行的字节数。

最简单的方法是对您读入的每一行,使用 getBytes,提供写入文件的字符编码,然后获取其长度。这可能不是最有效的方法,但会非常准确且简单易行。

或者,您可以一次读取固定数量的字节,然后自己维护一个缓冲区来处理部分单词和换行符。

关于java - 在不阅读完整文件的情况下估计文件的字数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3516779/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com