如何用ruby替換文件的全部內容?用ruby替換文件的全部內容?
Dir["#{File.dirname(__FILE__)}/data/**/*.json"].each do |f|
encoded = f.read.force_encoding('UTF-16').encode('utf-8')
# ????????
end
我想重新編碼一些json文件的內容。
如何用ruby替換文件的全部內容?用ruby替換文件的全部內容?
Dir["#{File.dirname(__FILE__)}/data/**/*.json"].each do |f|
encoded = f.read.force_encoding('UTF-16').encode('utf-8')
# ????????
end
我想重新編碼一些json文件的內容。
這應該工作:
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
的編碼參數自動處理轉換。
這產生了一些樣品的測試數據:
# encoding: UTF-8
require 'json'
foo = {'a'=>%w[a b ç ∂]}
JSON.dump(foo, File.new('filein.json', 'w:UTF-16'))
「filein.json」 是這樣的,當我cat
它:
��{"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