参数remote
可以是一个Pathname
对象,而参数local
设置时应该是一个String
或响应#write
方法的对象。下面是工作代码
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
中,下面是相关语句的代码片段。
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!
方法需要两个参数,如下所示
sftp.download!(remote, local)
给定的 argsremote
并在此处local
转换为 Entry 对象
[Entry.new(remote, local, recursive?)]
Entry
只是这里_Struct
Entry = Struct.new(:remote, :local, :directory, :size, :handle, :offset, :sink)
好吧那什么是sink
属性?我们会马上跳到那个..
一旦打开相关的远程文件以供读取,该方法就会使用此处的文件处理程序#on_open
更新此属性。sink
找到下面的片段,
entry.sink = entry.local.respond_to?(:write) ? entry.local : ::File.open(entry.local, "wb")
这实际上只发生在给定local
的路径对象没有实现它自己的#write
方法在我们的场景中,Pathname
对象确实响应写入
下面是控制台输出的一些片段,我在调试时在多个下载块调用之间进行了检查。它显示entry
并entry.sink
显示了上面讨论的对象。在这里,我选择我的遥控器作为Pathname
对象,本地作为String
路径,通过成功下载返回正确的值entry.sink
和那里..
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>