我消耗数据的饲料最近已增加了一个Unicode BOM header(U+FEFF),和我耙的任务是现在搞砸了它。

我可以跳过的第3字节 file.gets[3..-1] 但是有一个更优雅的方式阅读的文件,在红宝石,它可以处理这一正确,是否物料清单是本或没有?

有帮助吗?

解决方案

使用红宝石1.9.2可以使用模式r:bom|utf-8

text_without_bom = nil #define the variable outside the block to keep the data
File.open('file.txt', "r:bom|utf-8"){|file|
  text_without_bom = file.read
}

text_without_bom = File.read('file.txt', encoding: 'bom|utf-8')

text_without_bom = File.read('file.txt', mode: 'r:bom|utf-8')

不要紧,如果BOM是文件或不在可用的。


您还可以使用编码选项与其它命令:

text_without_bom = File.readlines(@filename, "r:utf-8")

(你得到与所有线的阵列)。

或者与CSV:

require 'csv'
CSV.open(@filename, 'r:bom|utf-8'){|csv|
  csv.each{ |row| p row }
}

其他提示

我不会盲目跳过第一三个字节;什么如果生产者 停止 添加的物料清单一次?你应该做的是 检查 第一个数字,并且如果他们0xEF0xBB0xBF,忽略他们。这种形式的物料清单character(U+FEFF)需要在UTF-8;我更喜欢处理这之前试图解码流,因为物料清单处理是很不一致,从一个语言/工具/框架的下一步。

事实上,这就是你如何 应该 要处理的物料清单。如果文件已作为UTF-16,你必须审查的头两个字节之前开始解码所以你知道是否阅读它,因为big-endian little-endian.当然,UTF-8BOM没有字节的顺序,就只有让你知道,该编码是UTF-8,在的情况下,你不是已经知道这一点。

我不“信任”某些文件编码为UTF-8时0xEF为0xBB 0xBF时才的BOM存在,你可能会失败。一般检测UTF-8 BOM时,它应该是顺理成章的UTF-8编码的文件。但是,例如,如果某人刚刚添加的UTF-8 BOM到ISO文件,你不能编码这样的文件如此糟糕,如果有在它是上面为0x0F字节。如果你只有字节最多为0x0F里面,因为在这种情况下,它是一个UTF-8兼容的ASCII文件,并在同一时间,它是一个合法的UTF-8文件,你可以信任的文件。

如果有不只是字节<=为0x0F的文件(BOM后),以确保它是正确的UTF-8编码,你必须检查有效的序列中 - 即使所有序列有效 - 检查如果还从一个序列中的每个代码点使用最短序列可能,并且还检查是否存在没有码点,一个高或低的替代匹配。同时检查序列的最大字节数不超过4,最高码点在0x10FFFF。最高限额码点也startbyte的有效载荷位应不小于为0x4高,随后第一个字节的有效载荷比0xF不高。如果所有提到的检查顺利过关,你的UTF-8 BOM道出了实情。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top