0

我需要做一些文件大小至关重要的事情。这产生了奇怪的结果

filename = "testThis.txt"
total_chars = 0
file = File.new(filename, "r")
file_for_writing = nil
while (line = file.gets)
  total_chars += line.length
end
puts "original size #{File.size(filename)}"
puts "Totals #{total_chars}"

像这样

original size 20121
Totals 20061

为什么第二个短了?

编辑:回答者的预感是正确的:测试文件中有 60 行。如果我改变这条线

  total_chars += line.length + 1

它完美地工作。但是在 *nix 上,这种变化会不会出错?

编辑:跟进现在在这里。谢谢!

4

3 回答 3

5

文件中存储了用于描述行的特殊字符:

  • CR LF (0x0D 0x0A) (\r\n) 在 Windows/DOS 和
  • UNIX 系统上的 0x0A (\n)。

Rubygets使用 UNIX 方法。因此,如果您读取 Windows 文件,您将在读取的每一行中丢失 1 个字节,因为 \r\n 字节被转换为 \n。

也不String.length是衡量字符串大小(以字节为单位)的好方法。如果字符串不是 ASCII,则一个字符可能由多个字节 (Unicode) 表示。也就是说,它返回字符串中的字符数,而不是字节数。

要获取文件的大小,请使用File.size(file_name).

于 2009-03-09T10:47:00.733 回答
3

我的猜测是您在 Windows 上,并且您的“testThis.txt”文件有 \r\n 行结尾。当文件以文本模式打开时,每一行结尾都将转换为单个 \n 字符。因此,您每行将丢失 1 个字符。

你的测试文件有 60 行吗?这与这个解释是一致的。

于 2009-03-09T10:43:57.153 回答
3

行尾问题是最有可能的罪魁祸首。

还值得注意的是,如果文本文件的字符编码不是 ASCII,那么两者之间也会有差异。如果文件是 UTF-8,这将适用于仅使用标准 ASCII 字母符号的英语和一些欧洲语言。除此之外,文件大小和字符数可能会有很大差异(与字符数相比,文件大小最多是文件大小的 4 倍甚至 6 倍)。

依赖“1 个字符 = 1 个字节”只是自找麻烦,因为它几乎肯定会在某个时候失败。

于 2009-03-09T10:54:56.517 回答