Sinatra params 循环会出错,大家有没有遇到过

tiseheaini · 2013年05月02日 · 最后由 zj0713001 回复于 2013年05月02日 · 4422 次阅读

功能很简单,用 ruby 脚本将一个目录内的文件利用 http post 发给服务器端,然后服务器端将接收到的文件保存起来 ruby 脚本

require "net/http"
require "find"
require "rest_client"

file_path = "/home/tiny/log"

file_list = []
file_hash = {}
Find.find(file_path) do |path|
  next if File.ftype(path) == "directory"
  file_list << path
end

file_list.each do |file|
  file_hash[file] = File.new(file, "rb")
end

RestClient.post("http://localhost:4567/uploads", :info => file_hash)

服务器端使用的 Sinatra

get '/' do
  "main"
end

post '/uploads' do
  Dir.mkdir(File.join(Dir.home, "assets")) if !File.exist?(File.join(Dir.home, "assets"))

  puts params[:info].class
  puts params[:info].size
  puts params[:info]

  params[:info].each do |file_name, file|
    puts file_name.class
    puts file.class
  end

end

信息

Hash
2
{"/home/tiny/log/log.txt"=>{:filename=>"log.txt", :type=>"text/plain", :name=>"info[/home/tiny/log/log.txt]", :tempfile=>#<File:/tmp/RackMultipart20130502-21736-1rkyz6s>, :head=>"Content-Disposition: form-data; name=\"info[/home/tiny/log/log.txt]\"; filename=\"log.txt\"\r\nContent-Type: text/plain\r\n"}, "/home/tiny/log/zuijin.txt"=>{:filename=>"zuijin.txt", :type=>"text/plain", :name=>"info[/home/tiny/log/zuijin.txt]", :tempfile=>#<File:/tmp/RackMultipart20130502-21736-16i7d6j>, :head=>"Content-Disposition: form-data; name=\"info[/home/tiny/log/zuijin.txt]\"; filename=\"zuijin.txt\"\r\nContent-Type: text/plain\r\n"}}
!! Unexpected error while processing request: Body yielded non-string value ["/home/tiny/log/log.txt", {:filename=>"log.txt", :type=>"text/plain", :name=>"info[/home/tiny/log/log.txt]", :tempfile=>#<File:/tmp/RackMultipart20130502-22154-1vc7awj>, :head=>"Content-Disposition: form-data; name=\"info[/home/tiny/log/log.txt]\"; filename=\"log.txt\"\r\nContent-Type: text/plain\r\n"}]
127.0.0.1 - - [02/May/2013 12:17:44] "POST /uploads HTTP/1.1" 200 - 0.0354

当取消 params[:info] 循环的时候,

!! Unexpected error while processing request: Body yielded non-string value ["/home/tiny/log/log.txt", {:filename=>"log.txt", :type=>"text/plain", :name=>"info[/home/tiny/log/log.txt]", :tempfile=>#<File:/tmp/RackMultipart20130502-22154-1vc7awj>, :head=>"Content-Disposition: form-data; name=\"info[/home/tiny/log/log.txt]\"; filename=\"log.txt\"\r\nContent-Type: text/plain\r\n"}]

就没有这样的信息了 不知道大家有没有遇到过这样的问题??

puts params[:info].inspect

#1 楼 @zgm 这个目录里面只有两个文件 log.txt 和 zuijin.txt 文件名做 key 文件做 value

{"/home/tiny/log/log.txt"=>{:filename=>"log.txt", :type=>"text/plain", :name=>"info[/home/tiny/log/log.txt]", :tempfile=>#<File:/tmp/RackMultipart20130502-22593-1824t4f>, :head=>"Content-Disposition: form-data; name=\"info[/home/tiny/log/log.txt]\"; filename=\"log.txt\"\r\nContent-Type: text/plain\r\n"}, "/home/tiny/log/zuijin.txt"=>{:filename=>"zuijin.txt", :type=>"text/plain", :name=>"info[/home/tiny/log/zuijin.txt]", :tempfile=>#<File:/tmp/RackMultipart20130502-22593-l3kqn7>, :head=>"Content-Disposition: form-data; name=\"info[/home/tiny/log/zuijin.txt]\"; filename=\"zuijin.txt\"\r\nContent-Type: text/plain\r\n"}}

这个搞法太强悍了。。。。

#3 楼 @hhuai 什么意思?不懂哪里强悍

#4 楼 @tiseheaini 最后要返回一个字符串。

#5 楼 @zgm 可是,我需要循环处理这个 Hash,只有这样才能保存这个文件

#6 楼 @tiseheaini 你怎么处理是你的事,你最后返回一个“success”之类的字符串就行了

#7 楼 @zgm 我试了试,可以通过,不过这样的解决方式也太恶心了

#8 楼 @tiseheaini 你不符合规矩,怎么说他恶心啊。你看看 rack 的规范。

#8 楼 @tiseheaini 没让你写数组已经不错了。

#10 楼 @zgm 哇,sinatra 真不好玩

#11 楼 @tiseheaini 你要求太高了。哎。

#12 楼 @zgm 前天还以为 sinatra 挺好玩,php 弱爆了,今天我就不这么认为了

rsync 就可以了,何必呢。

讨论不着调,跟 sinatra 有什么关系。 File.new 出来是一个对象,包含的就一个文件句柄,你序列化传到服务器有什么用?

#15 楼 @hhuai 那应该如何用脚本上传一个文件?有没有更好的解决方法

#16 楼 @tiseheaini 如果文件的确很小,你可以直接 read 出来再 post

file_hash[file] = File.new(file, "rb").read

也可以打包一起上传,算了,先不考虑,等你有性能问题再讨论吧。

撸主 我真心觉得最好先提高一下 ruby 代码的水平再想怎么解决问题... 看你的第一个脚本 都想哭了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号