Libssh2 停止读取大文件

Libssh2 stop reading large file

我需要通过 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 实现)的文档:

It is not an error if the returned value n is smaller than the buffer size, even when the reader is not at the end of the stream yet. This may happen for example because fewer bytes are actually available right now (e. g. being close to end-of-file) or because read() was interrupted by a signal.

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

如果您确定有足够的传入数据来填充缓冲区,则可以使用 read_exact,但请注意,如果可用数据比缓冲区短,这将 return 出错.

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