在Ruby中打开文件返回空文件

时间:2015-07-29 18:13:33

标签: ruby-on-rails ruby pdf

我目前正在尝试将一个pdf存储在一个哈希中,用于在ruby中进行api调用。 pdf的路径存储为:

/Users/myUserName/Desktop/REPOSITORY/path_to_file.pdf

我正在使用块将文件存储在哈希中,如下所示:

File.open(pdf_location, "rb") do |file|
        params = {
          other irrelevant entries
          :document => file
        }
        pdf_upload_request('post', params, headers)
end

我从服务器收到400错误,我的文档为空,当我puts file.read时,它是空的。但是,当我访问文件路径时,它清楚该文件不为空。我在这里错过了什么吗?任何帮助将不胜感激。谢谢!

编辑------

我用vcr录制了我的http请求,这里是:

request:
    method: post
    uri: request_uri
    body:
      encoding: US-ASCII
      string: ''
    headers:
      Authorization:
      - Bearer 3ZOCPnwfoN7VfdGh7k4lrBuEYs4gN1
      Content-Type:
      - multipart/form-data; boundary=-----------RubyMultipartPost
      Content-Length:
      - '246659'

所以我不认为问题在于我发送带有多部分编码的文件

更新--------

pdf的文件路径是从url生成的,并存储在我的应用程序的tmp文件夹中。它们是通过这种方法生成的:

def get_temporary_pdf(chrono_detail, recording, host)
    auth_token = User.find(chrono_detail.user_id).authentication_token
      # pdf_location = "https://54.84.224.252/recording/5/analysis.pdf/?token=Ybp37kw7HrSt8NyyPnBZ"
    pdf_location = host + '/recordings/' + recording.id.to_s + '/analysis.pdf/?format=pdf&download=true&token=' + auth_token
    filename = "Will" + '_' + recording.id.to_s + '_' + Date.new.to_s + '.pdf'
    Thread.new do
      File.open(Rails.root.join("tmp",filename), "wb") do |file|
        file.write(open(pdf_location, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}).read)
      end
    end
    Rails.root.join("tmp",filename)
  end 

然后使用api调用调用它们:

client.upload_document(patient_id, file_path, description)

我可以在我的临时文件夹中看到它们,并可以通过预览查看它们。一切似乎都有效。但作为对不确定性的测试,我将file_path更改为指向不同的pdf:

Users/myUsername/Desktop/example.pdf.

使用此文件路径有效。 pdf已正确上传到第三方系统,我可以在那里看到它。你认为这意味着它是tmp文件夹的一个问题,或者我是如何生成临时pdf的?

3 个答案:

答案 0 :(得分:1)

最有可能的是,API期待POST为Content-Type: multipart/form-data。只发送文件句柄(document: file执行)不起作用,因为文件句柄只与本地Ruby进程相关;甚至将二进制字符串作为参数发送也不起作用,因为您的内容类型未正确设置为对文件进行编码。

由于您已经在使用HTTParty,因此可以使用HTTMultiParty解决此问题:

require 'httmultiparty'
class SomeClient
  include HTTMultiParty
  base_uri 'http://localhost:3000'
end

SomeClient.post('/', :query => {
  :foo      => 'bar',
  :somefile => File.new('README.md')
})

答案 1 :(得分:0)

试试这个:

file = File.read(pdf_location)
params = {
  # other irrelevant entries
  document: file
}
headers = {}
pdf_upload_request('post', params, headers)

不确定但可能需要先关闭文件...

答案 2 :(得分:0)

因此问题来自我用来避免超时错误的多线程。在将任何内容实际写入文档之前,将在api调用中生成并引用文件路径。