我正在創建一個包含文本文件和圖像文件的Zip文件。代碼在MacOS上運行時按預期工作,但在Windows上運行時會失敗,因爲圖像文件內容讀取不正確。在Windows上使用Ruby讀取PNG文件失敗
下面的代碼段總是將PNG圖像文件讀取爲'PNG',在Zip中爲每個PNG圖像添加一個5字節的文件。
這是Windows環境的問題嗎?
zip_fs.file.open(destination, 'w') do |f|
f.write File.read(file_name)
end
我正在創建一個包含文本文件和圖像文件的Zip文件。代碼在MacOS上運行時按預期工作,但在Windows上運行時會失敗,因爲圖像文件內容讀取不正確。在Windows上使用Ruby讀取PNG文件失敗
下面的代碼段總是將PNG圖像文件讀取爲'PNG',在Zip中爲每個PNG圖像添加一個5字節的文件。
這是Windows環境的問題嗎?
zip_fs.file.open(destination, 'w') do |f|
f.write File.read(file_name)
end
我在閱讀Lib文件時遇到類似問題。這裏是我的解決方案:
File.open(path + '\Wall.Lib')
其中路徑對應於輸入文件名的JavaScript文件。
從Why are binary files corrupted when zipping them?
io.get_output_stream(zip_file_path) do |out|
out.write File.binread(disk_file_path)
end
你需要告訴Ruby來讀/以二進制方式寫入文件。這裏有一個主題一些變化:
zip_fs.file.open(destination, 'wb') do |f|
File.open(file_name, 'rb') do |fi|
f.write fi.read
end
end
zip_fs.file.open(destination, 'wb') do |f|
f.write File.read(file_name, 'mode' => 'rb')
end
zip_fs.file.open(destination, 'wb') do |f|
f.write File.readbin(file_name)
end
與代碼的一個潛在問題是輸入文件被咕嚕咕嚕,而如果它比可用空間大,將是一件壞事。最好是以塊的形式讀取輸入文件。這是未經測試,但應該工作:
BLOCK_SIZE = 1024 * 1024
zip_fs.file.open(destination, 'wb') do |f|
File.open(file_name, 'rb') do |fi|
while (block_in = fi.read(BLOCK_SIZE)) do
f.write block_in
end
end
end
已打開永遠不會關閉該文件。使用File.binread
我最初的代碼被寫入顯示時需要使用二進制模式,並用open
,因爲它是「傳統的」,卻忘了使用塊模式(FILE_NAME)。我修改了示例代碼來解決這個問題。
但是,當腳本結束時解釋器關閉時,該文件將由Ruby隱式關閉,作爲發生的內務處理的一部分。但是,最好明確close
該文件。如果OP使用我認爲的RubyZip,那麼如果一個塊被傳遞給open
,那麼將自動發生。否則,read
和readbin
都將讀取到EOF並關閉文件。如果輸入文件是未知大小或大於可用緩衝區空間,則使用這些方法的代碼需要對讀取塊的需求敏感。
這個文件被打開將永遠不會關閉。使用'File.binread(file_name)'。 –
[爲什麼二進制文件在壓縮時損壞?](http://stackoverflow.com/questions/10564283/why-are-binary-files-corrupted-when-zipping-them) –