如何在ruby中替换文件的全部内容?
Dir["#{File.dirname(__FILE__)}/data/**/*.json"].each do |f|
encoded = f.read.force_encoding('UTF-16').encode('utf-8')
# ????????
end
我正在尝试重新编码某些json文件的内容。
答案 0 :(得分:4)
这应该有效:
Dir["#{File.dirname(__FILE__)}/data/**/*.json"].each do |f|
begin
data = open(f, "r:utf-16:utf-8") {|fp| fp.read }
open(f, "w") {|fp| fp << data }
rescue Encoding::InvalidByteSequenceError
# Source data isn't in UTF-16, so skip this file.
next
end
end
一般的想法是我们将文件打开为UTF-16,将其读入UTF-8编码的字符串,然后将其写回(如UTF-8)。传递给IO.open
的编码参数会自动处理转换。
答案 1 :(得分:2)
这会创建一些示例测试数据:
# encoding: UTF-8
require 'json'
foo = {'a'=>%w[a b ç ∂]}
JSON.dump(foo, File.new('filein.json', 'w:UTF-16'))
当我cat
时,“filein.json”看起来像这样:
��{"a":["a","b","�","""]}
创建后,其中任何一个似乎都有效:
File.open('fileout.json', 'w:UTF-8') do |fo|
File.open('filein.json', 'rb:UTF-16') do |fi|
fo.write(fi.read)
end
end
它只是通过立即写入读入内存;它不可扩展,但合理大小的文件应该处理好。输入读为UTF-16,输出写为UTF-8。
JSON.dump(
JSON.load(File.open('filein.json', 'rb:UTF-16')),
File.open('fileout.json', 'w:UTF-8')
)
这与前面的示例类似,但它允许JSON gem解码然后重新编码文件。这可能是有用的,也可能不是。并且,再次,它不可伸缩,因为读取将文件加载到内存中。
对于超出内存的 BIG 文件,或者如果您只想做正确的事情并使用可扩展的代码,请使用:
File.open('fileout.json', 'w:UTF-8') do |fo|
File.foreach('filein.json', $/, encoding: 'UTF-16', mode: 'rb') do |li|
fo.write(li)
end
end
上面所有情况下创建的输出“fileout.json”是:
{"a":["a","b","ç","∂"]}
要使用Dir[]
进行搜索,请按照以下方式修改任何示例:
Dir[File.dirname(__FILE__) + '/data/**/*.json'].each do |filein|
File.open(filein + '.new', 'w:UTF-8') do |fo|
File.foreach(filein, $/, encoding: 'UTF-16', mode: 'rb') do |li|
fo.write(li)
end
end
end
对于每个输入文件,这将生成一个免费的“.json.new”文件。立即覆盖旧文件永远不会安全,因此在运行后您可以根据需要重命名*.new
文件。我会用:
Dir[File.dirname(__FILE__) + '/data/**/*.json'].each do |filein|
new_file = "#{ filein }.new"
File.open(new_file, 'w:UTF-8') do |fo|
File.foreach(filein, $/, encoding: 'UTF-16', mode: 'rb') do |li|
fo.write(li)
end
end
File.mv(filein, "#{ filein }.bak")
File.mv(new_file, filein)
end