2011-02-01 93 views
5

假設我想使用curl這種方式把一個文件到WebService西納特拉和HTTP PUT

curl -v --location --upload-file file.txt http://localhost:4567/upload/filename 

在西納特拉我可以這樣做:

#!/usr/bin/env ruby 

require 'rubygems' 
require 'sinatra' 

put '/upload/:id' do 
    # 
    # tbd 
    # 
end 

我如何可以讀取流文件?

或多或少我想是這樣的: http://www.php.net/manual/en/features.file-upload.put-method.php#56985

+0

[這個問題](http://stackoverflow.com/questions/4795205/streaming-web-uploads-to-socket-with-rack)意味着你想要的不能完成,但我還不知道足以確保將其作爲答案發布。 – Phrogz 2011-02-02 03:12:57

+0

@Phrogz我剛剛發現這個:http://groups.google.com/group/rack-devel/msg/600825afa08474d8 - 以爲你可能會感興趣。 – matt 2011-06-29 21:17:22

回答

4

最基本的例子是它給你寫信是在沒有檢查現有的文件運行西納特拉確認當期目錄...只是重挫他們。

#!/usr/bin/env ruby 

require 'rubygems' 
require 'sinatra' 

put '/upload/:id' do 
    File.open(params[:id], 'w+') do |file| 
    file.write(request.body.read) 
    end 
end 

另外,你可以在curl命令中忽略文件名部分,它會用文件名填充它。敵人例如:

curl -v --location --upload-file file.txt http://localhost:4567/upload/ 

將導致文件寫入到http://localhost:4567/upload/file.txt

2
require 'rubygems' 
require 'sinatra' 
require 'ftools' 

put '/upload' do 
    tempfile = params['file'][:tempfile] 
    filename = params['file'][:filename] 
    File.mv(tempfile.path,File.join(File.expand_path(File.dirname(File.dirname(__FILE__))),"public","#{filename}")) 
    redirect '/' 
end 

通過這種方式,你不必擔心文件的大小,因爲他不是在開(readed)內存,但只是從臨時目錄移動到正確的位置,跳過一個重要的攔截器。實際上,php代碼的功能相同,只需以1k塊的形式讀取文件並存儲在一個新文件中,但由於文件相同,所以它毫無意義。 嘗試你可以按照本的答案。