首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Net::SFTP错误

Net::SFTP错误
EN

Stack Overflow用户
提问于 2014-07-23 20:11:57
回答 2查看 2.2K关注 0票数 1

我一直试图使用Net::SFTP下载一个文件,它一直收到一个错误。

文件是部分下载的,只有2.1MB,所以它不是一个巨大的文件。我删除了文件上的循环,甚至尝试下载一个文件,得到了相同的错误:

代码语言:javascript
复制
yml = YAML.load_file Rails.root.join('config', 'ftp.yml')
Net::SFTP.start(yml["url"], yml["username"], password: yml["password"]) do |sftp|
  sftp.dir.glob(File.join('users', 'import'), '*.csv').each do |f|
    sftp.download!(File.join('users', 'import', f.name), Rails.root.join('processing_files', 'download_files', f.name), read_size: 1024)
  end
end
代码语言:javascript
复制
NoMethodError: undefined method `close' for #<Pathname:0x007fc8fdb50ea0>
from /[my_working_ap_dir]/gems/net-sftp-2.1.2/lib/net/sftp/operations/download.rb:331:in `on_read'

我已经向谷歌祈祷,我已经尽我所能,也不会用它取得任何进展。

EN

回答 2

Stack Overflow用户

发布于 2014-07-23 21:17:18

显然,您不能使用Rails.root.join,这是造成问题的原因。但是,它确实很愚蠢,因为它会下载文件的一部分。

更改:

代码语言:javascript
复制
sftp.download!(File.join('users', 'import', f.name), Rails.root.join('processing_files', 'download_files', f.name))

至:

代码语言:javascript
复制
sftp.download!(File.join('users', 'import', f.name), File.join('processing_files', 'download_files', f.name))
票数 2
EN

Stack Overflow用户

发布于 2020-08-27 18:45:32

参数remote可以是Pathname对象,而参数local在设置时应该是String,或者是响应#write方法的对象。下面是工作代码

代码语言:javascript
复制
local_stringified_path = Rails.root.join('processing_files', f.name).to_s
sftp.download!(Pathname.new('/users/import'), local_stringified_path)

对于所有好奇的人,请阅读下面的文章来理解这种行为。

NoMethodError: undefined method close' for #<Pathname:0x007fc8fdb50ea0>#on_read方法中恰好发生这里问题,下面是相关语句的代码片段。

代码语言:javascript
复制
if response.eof? 
   update_progress(:close, entry)
   entry.sink.close # ERRORED OUT LINE.. ideally when eof, file IO handler is supposed to be closed

什么是entry.sink

我们已经知道#download!方法需要两个args,如下所示

代码语言:javascript
复制
sftp.download!(remote, local)

给定的args remotelocal被转换为条目对象这里

代码语言:javascript
复制
[Entry.new(remote, local, recursive?)]

Entry不过是一个Struct 这里

代码语言:javascript
复制
Entry = Struct.new(:remote, :local, :directory, :size, :handle, :offset, :sink)

好的,那么sink属性是什么?我们马上跳过去.

一旦打开要读取的相关远程文件,#on_open方法将使用文件处理程序这里更新此sink属性。

找到下面的片段,

代码语言:javascript
复制
entry.sink = entry.local.respond_to?(:write) ? entry.local : ::File.open(entry.local, "wb")

实际上,只有当给定local #write路径对象没有实现它自己的#write方法时,Pathname对象才会发生这种情况,在我们的场景中,Pathname对象确实响应

下面是控制台输出的一些片段,我在调试时在多个下载块调用之间进行了检查。它显示了显示上述讨论对象的entryentry.sink。在这里,我选择了我的遥控器为Pathname对象,本地为String路径,它通过成功下载返回entry.sink和那里的适当值。

代码语言:javascript
复制
0> entry 
=> #<struct Net::SFTP::Operations::Download::Entry remote=#<Pathname:214010463.xml>, local="214010463.xml", directory=nil, size=nil, handle="1", offset=32000, sink=#<File:214010463.xml>>


0> entry.sink
=> #<File:214010463.xml>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24920056

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档