所以我有一些代码可以检查远程SFTP服务器上是否有某个文件:
def size
adapter.sftp.stat(path).size
end
其中sftp
是Net :: SFTP :: Session对象,在本例中定义为
@sftp = Net::SFTP.start(host, username, password: password)
和path
是我想要调用stat()
的对象的文件路径。
不幸的是,当我尝试执行此代码时,我收到此错误:
NoMethodError:
undefined method `send_data' for nil:NilClass
# /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:814:in `send_packet'
# /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/protocol/base.rb:45:in `send_request'
# /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/protocol/01/base.rb:90:in `open'
# /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:830:in `request'
# /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:182:in `open'
# /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/session.rb:191:in `open!'
# /usr/local/lib/ruby/gems/2.2.0/gems/net-sftp-2.1.2/lib/net/sftp/operations/file_factory.rb:40:in `open'
# /Users/Ben/remote_filesystem/lib/remote_filesystem/path/sftp.rb:46:in `size'
# ./sftp_spec.rb:72:in `block (3 levels) in <top (required)>'
据我所知,从查看Net :: SFTP :: Session的源代码,session.rb
的第814行,channel.send_data
被调用,但显然我的SFTP会话有一个Nil渠道出于某种原因。任何人都可以解释如何解决这个问题吗?
答案 0 :(得分:0)
如果您正在缓存sftp
,则缓存可能已失效。我遇到了这个例外情况,因为我曾尝试在ftp.file.open
连接上拨打ftp
,该连接已不再打开。
答案 1 :(得分:0)
如前所述,这意味着您的SFTP会话已终止。
检查TCP日志(wireshark是你的朋友),同时会话终止会话。
发生此类错误的情况是您正在进行数据长度超过接收端TCP窗口大小的写入(数据)操作。修复方法是使用缓冲区重复写操作,如
io = StringIO.new(data)
sftp_session.file.open(filename, "w") do |file|
while buffer = io.read(BUFFER_SIZE)
file.write(buffer)
end
end