微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Libssh2停止读取大文件

如何解决Libssh2停止读取大文件

我需要通过ssh读取一些文件,但是当我循环读取该文件时...它将停止。
在我的Cargo.toml中,我具有以下依赖性:

[dependencies]
ssh2 = "0.8"

取决于libssh2。
代码更复杂,但是我设法用这个肮脏的代码重现了这个问题:

  use std::fs::File;
  use std::io::Read;
  use std::io::Write;
  #[allow(unused_imports)]
  use std::io::Error;
  use std::net::Tcpstream;
  use ssh2::Session;
  use std::path::Path;
  use std::io::prelude::*;

  fn main() {
      println!("Parto!");

      let tcp = Tcpstream::connect("myhost:22").unwrap();
      let mut sess = Session::new().unwrap();
      sess.set_tcp_stream(tcp);
      sess.handshake().unwrap();
      sess.userauth_password("user","password").unwrap();
      assert!(sess.authenticated());

      let (mut remote_file,stat) = sess.scp_recv(Path::new("/home/pi/dbeaver.exe")).unwrap();
      println!("remote file size: {}",stat.size());
      let mut buf: Vec<u8> = vec![0;1000];

      loop {
          let read_bytes = remote_file.read(&mut buf).unwrap();
          println!("Read bytes: {}.",read_bytes);
          if read_bytes < 1000 {
              break;
          }
      } //ending loop
  }

我在Windows 10和Linux Debian上都进行了测试。当文件读取的内容多于几个KB时,问题始终存在:

let read_bytes = remote_file.read(&mut buf).unwrap();

读取的数据小于缓冲区大小(但文件未结束)。
已对二进制文件或asci文件进行了测试。

没有错误,它只是停止阅读。奇怪的是:它有时停止在8 MB,有时停止在16 KB。具有相同的文件和主机...

我需要在哪里挖掘或需要检查什么?

解决方法

从文档中引用io::Read特性(ssh2实现):

即使返回值n小于缓冲区大小,这也不是错误,即使读取器不在流的末尾也是如此。例如,这可能是因为当前实际可用的字节较少(例如,接近文件末尾)或因为信号中断了read()。

由于您正在远程阅读,这可能仅意味着剩余字节仍在网络中传输,并且在目标计算机上尚不可用。

如果您确定有足够的传入数据填充缓冲区,则可以使用read_exact,但是请注意,如果可用数据短于缓冲区,则会返回错误。

编辑:或者甚至更好,使用read_to_end,它不需要事先知道大小(我不知道为什么昨天写原始答案时看不到它的大小)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。