2013-06-03 36 views
0

我正在創建一個包含文本文件和圖像文件的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 
+0

[爲什麼二進制文件在壓縮時損壞?](http://stackoverflow.com/questions/10564283/why-are-binary-files-corrupted-when-zipping-them) –

回答

0

我在閱讀Lib文件時遇到類似問題。這裏是我的解決方案:

File.open(path + '\Wall.Lib') 

其中路徑對應於輸入文件名的JavaScript文件。

1

你需要告訴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,那麼將自動發生。否則,readreadbin都將讀取到EOF並關閉文件。如果輸入文件是未知大小或大於可用緩衝區空間,則使用這些方法的代碼需要對讀取塊的需求敏感。

+0

這個文件被打開將永遠不會關閉。使用'File.binread(file_name)'。 –

相關問題