提问人:ujifgc 提问时间:3/27/2012 更新时间:11/16/2023 访问量:10391
如何在 Ruby 中将 BOM 标记写入文件
How to write BOM marker to a file in Ruby
问:
我有一些带有拐杖的工作代码,用于将 BOM 标记添加到新文件中。
#writing
File.open name, 'w', 0644 do |file|
file.write "\uFEFF"
file.write @data
end
#reading
File.open name, 'r:bom|utf-8' do |file|
file.read
end
有没有办法自动添加标记而不在数据前写神秘?也许是这样?"\uFEFF"
File.open name, 'w:bom' # this mode has no effect
答:
5赞
Michael Kohl
3/27/2012
#1
唉,我认为您的手动方法是要走的路,至少我不知道更好的方法:
http://blog.grayproductions.net/articles/miscellaneous_m17n_details
引用 JEG2 的文章:
Ruby 1.9 不会自动将 BOM 添加到您的数据中,因此您需要 如果你想要一个,就需要照顾它。幸运的是,它不是太 艰难。基本思想只是打印所需的字节 文件的开头。
评论
2赞
tchrist
3/28/2012
您不希望 UTF-8 文件中的 BOM!!
4赞
fab
8/4/2015
您能解释一下我们为什么不想这样做吗?:) @tchrist
0赞
barlop
12/13/2017
@fab,因为 UTF8 没有必要。使用 utf16 时,bom 指示文件是大端还是小端,一个有一个 bom,另一个有一个 bom,并且 bom 是必需的,但是使用 utf8 时没有两个变体 bom,bom 是不必要的 stackoverflow.com/questions/2223882/......
11赞
knut
3/27/2012
#2
这个答案引出了一个新的宝石:file_with_bom ****
我过去也遇到过类似的问题,我扩展了 -mode 的其他编码变体:File.open
w
class File
BOM_LIST_hex = {
Encoding::UTF_8 => "\xEF\xBB\xBF", #"\uEFBBBF"
Encoding::UTF_16BE => "\xFE\xFF", #"\uFEFF",
Encoding::UTF_16LE => "\xFF\xFE",
Encoding::UTF_32BE => "\x00\x00\xFE\xFF",
Encoding::UTF_32LE => "\xFE\xFF\x00\x00",
}
BOM_LIST_hex.freeze
def utf_bom_hex(encoding = external_encoding)
BOM_LIST_hex[encoding]
end
class << self
alias :open_old :open
def open(filename, mode_string = 'r', options = {}, &block)
#check for bom-flag in mode_string
options[:bom] = true if mode_string.sub!(/-bom/i,'')
f = open_old(filename, mode_string, options)
if options[:bom]
case mode_string
#r|bom already standard since 1.9.2
when /\Ar/ #read mode -> remove BOM
#remove BOM
bom = f.read(f.utf_bom_hex.bytesize)
#check, if it was really a bom
if bom != f.utf_bom_hex.force_encoding(bom.encoding)
f.rewind #return to position 0 if BOM was no BOM
end
when /\Aw/ #write mode -> attach BOM
f = open_old(filename, mode_string, options)
f << f.utf_bom_hex.force_encoding(f.external_encoding)
end #mode_string
end
if block_given?
yield f
f.close
end
end
end
end #File
测试代码:
EXAMPLE_TEXT = 'some content öäü'
File.open("file_utf16le.txt", "w:utf-16le|bom"){|f| f << EXAMPLE_TEXT }
File.open("file_utf16le.txt", "r:utf-16le|bom:utf-8"){|f| p f.read }
File.open("file_utf16le.txt", "r:utf-16le:utf-8", :bom => true ){|f| p f.read }
File.open("file_utf16le.txt", "r:utf-16le:utf-8"){|f| p f.read }
File.open("file_utf8.txt", "w:utf-8", :bom => true ){|f| f << EXAMPLE_TEXT }
File.open("file_utf8.txt", "r:utf-8", :bom => true ){|f| p f.read }
File.open("file_utf8.txt", "r:utf-8|bom", ){|f| p f.read }
File.open("file_utf8.txt", "r:utf-8", ){|f| p f.read }
一些评论:
- 该代码来自 1.9 之前的代码(但它仍然有效)。
- 我用作 bom 指标(ruby 1.9 使用 .
-bom
|bom
一些需要修复才能变得更好:
- 改用
|bom
-bom
- 使用标准进行阅读
r|bom
- 使其启用 Ruby 1.8 和 1.9
也许我明天会找一些时间重构我的代码并将其作为宝石提供。
评论
0赞
ujifgc
3/27/2012
感谢您的建议,但对于我的项目来说,这将是矫枉过正。
0赞
Aleksander Pohl
3/27/2012
+1 宝石。我想你可以联系 Ruby 或 Rubinius 的人,并将其合并到官方发行版中。
0赞
knut
3/29/2012
@AleksanderPohl 宝石是 rubygems.org/gems/file_with_bom 出版的,我希望我没有疏忽。
1赞
aaron
1/8/2023
#3
@knut的修剪版本
File.open("file_utf8.txt", "w:utf-8") do |f|
f << "\xEF\xBB\xBF".force_encoding("UTF-8")
f << EXAMPLE_TEXT
end
0赞
chinacheng
11/16/2023
#4
试试这个
# read content form old file
original_content = File.read(file_path)
# define UTF-8 BOM
bom = "\xEF\xBB\xBF"
# new file,add BOM in the head of content
File.open(new_file_path, "w:UTF-8") do |file|
file.write(bom + original_content)
end
评论