2015-02-07 74 views
1

我想使用Ruby的Net :: FTP類來存儲二進制文件。該文件的內容由前一個進程放入管道中。我需要從管道(IO類)獲取字節並將其存儲(在/不需要臨時文件)到FTP服務器。Ruby Net :: FTP storbinary從管道輸入中寫入受損文件

如果我這樣做,這樣

ftp = Net::FTP.new(@@host, @@user, @@password) 
ftp.debug_mode = true 
ftp.passive = true 
ftp.binary = true 
ftp.storbinary("STOR #{name}", pipe, Net::FTP::DEFAULT_BLOCKSIZE) 
ftp.close 

存儲的文件的大小約爲500KB小於它應該是(正確的尺寸是約6.8 MB)。該文件包含gpg加密數據。如果試圖解密,我會得到一個錯誤。

直接從管道存儲到本地文件會導致文件的大小和正常工作解密。

我是比較新的紅寶石,有人可以給我一個提示嗎?調試的一些想法?我可以提供更多信息嗎?

感謝您的幫助


從網:: FTP輸出調試:

put: PASV 
get: 227 Entering Passive Mode (80,237,136,162,233,60). 
put: STOR test-ftp.tar.gz.gpg 
get: 150 Opening BINARY mode data connection for test-ftp.tar.gz.gpg 
get: 226 Transfer complete 

紅寶石版本:紅寶石2.1.5p273

操作系統:Linux的Debian的

環境:紅寶石腳本直接從bash執行

更多的代碼:

p_out, p_in = IO.pipe 
@@thread = Thread.new { 
    cmd = "gpg --no-tty --cipher-algo AES256 --compress-level 0 --passphrase-file #{@@cmd.results[:gpg_passphrase_file]} --symmetric" 
    # Execute gpg 
    Open3.popen3 (cmd) { |stdin, stdout, stderr, wait_thr| 

    Thread.new { 
     cnt = IO::copy_stream pipe, stdin 
     @@output.debug "GPG_Encryption::execute copied #{(Float(cnt)/1024/1024).round(2)} MiB bytes to gpg" 
     pipe.close 
     stdin.close 
    } 

    Thread.new { 
     cnt = IO::copy_stream stdout, p_in 
     @@output.debug "GPG_Encryption::execute copied #{(Float(cnt)/1024/1024).round(2)} MiB bytes from gpg" 
    } 

    # wait for gpg finished 
    wait_thr.join 

    # Close pipe (sends eof) 
    p_in.close 

    # check result 
    if 0 == wait_thr.value 
     @@output.info "gpg finished..."      
    else 
     @@output.error "gpg returned an error" 
     @@output.raw stderr.readlines.join 
     exit 1 
    end 
    } 
} 

ftp = Net::FTP.new(@@host, @@user, @@password) 
ftp.debug_mode = true 
ftp.passive = true 
ftp.binary = true 
ftp.storbinary("STOR #{name}", pipe, Net::FTP::DEFAULT_BLOCKSIZE) 
ftp.close 

回答

0

你可能會關閉該文件之前,FTP連接已經完全發送。嘗試刪除顯式ftp.close。您可能不需要它,因爲當垃圾收集到ftp時,連接將自動關閉。

+0

謝謝davogones,我只是試過了,但沒有區別。存儲的文件仍然很小。但是如果整個腳本在傳輸完成之前結束呢?有沒有辦法等待發送的所有內容,如連接線程? – PiperAtTheGatesOfDawn 2015-02-08 09:41:59