如何在大文件中使用ssh2_scp_recv(内存限制)

时间:2014-02-27 20:45:27

标签: php linux

如何在不扩展内存限制的情况下将ssh2_scp_recv用于非常大的文件?!

当我尝试下载非常大的文件时,我最终达到了内存限制!?

更新

private function ssh_copy($host, $file_remote, $file_local){
    $connection = ssh2_connect($host, 22);
    ssh2_auth_password($connection, 'root', $this->hosts[$host]['pass']);

    $sftp = ssh2_sftp($connection);
    $sftp_remote = "ssh2.sftp://$sftp$file_remote";
    echo $sftp_remote."\n";
    $remote = fopen($sftp_remote, 'rb');
    $local = fopen($file_local, 'w');

    echo $file_remote."\n";

    while(!feof($remote)){
        //fwrite($local, fread($remote, 8192));

        $chunk = fread($remote, 8192);
        echo strlen($chunk).' '.sha1($chunk)."\n";
    }

    fclose($local);
    fclose($remote);

    return $file_local;
}

输出

该文件大约50 MB,这只会永远持续......

ssh2.sftp://Resource id #3/var/bak/db/2014-02-27-2113_mysql.tar.gz
/var/bak/db/2014-02-27-2113_mysql.tar.gz
8192 5d6aaf93d52842b2a0cd1ed5b31dea8077f52722
8192 4e607553d49adbaf46450f757a8d573e655b3d8d
8192 458067e2f4cd96657e98ceed66c86edd26da35a5
8192 c08083f13297d23eb0461f907260dc74c4a89e9f
8192 1de0c28595edd853a62ed6a9e1f9ba12d382ef1b
8192 9118766479ce74c4235ff6c7ed5e775752a34ffd
8192 e82c715115ad64d811936d69fb8a214a57245777
8192 8f3477f762925ef9bf2f3d0db7bc0225654f42d4
8192 7e069131ce5f5dbbe25c34ae3f32b668feef9f94
8192 f855022d0b742031fa4ab621027452d60ccf4c9a
8192 51954b87f04166ed2cdca1e5eec0d6a7cdf8215d
8192 e6d09cd53385d8edbd04a2a8ac733fcf22b090ea
8192 f26acd9c704fc3c8635dd521a49bf22e12236ae3
8192 01dedf90438386552fae9175e547af0e977058d7
8192 688bc32c8e439e15bff4aa9327fe20b924cef5c0
8192 0be35c670a90c2ed23a372a5cb9d99976d755da0
8192 f5aca37bf6d31c67be33d09a7ca2d6684ef96398
8192 aebcbd18ba8729a6c92e19082171daf32dc87400
8192 0ff998f5a65cf28cd968e067bdee2b5c4bcce686
8192 1551790407a5390d54825482d468c4422bea5ba2
8192 672b1a47a77f218f7c6398ddfc048e341601f171
8192 72296f8fdb7031f5977b52ffd1e8dfb214efa61a
8192 053cd323db07d97b7dcaaf428e0eb09a84ac2b36
8192 c80b4cb4930b14aa21a8085dfeecbf94ec0d527d
8192 57d2b4267fbe1d8a80164af83d7c43d56dbb345b
8192 9d65c61c5adfdf99b37ca622f099fbed88721f69
8192 9210353d6b26db9bb0ff7418cf8dc69095a08eed
8192 5eddb200bd18731385351d5b974826df9d1bb821
8192 85cede3d85b379505c5586eab8386bc9f9d7a3c5
8192 82969ab7a72e8201b8d365e6bd9728ffc843292f
8192 ef6ad7797342f23789ee21a9f3dc9b4b048c0a4f
8192 b345f90819f55c7e6e024afc8da93e600153ad1d
8192 61fbd0611540a042d4bb9fb77aa7fd5a2156ad62
8192 3256b4f6a888f4e2cbe88aeb8a59d7e5cc6866f0
8192 9d6063880d60466fda376598b8fc74fad41a71f1
8192 88c1236e252ad24e1be62a9f90d5a74c70b00c6e
8192 348d8d4d30871fd8b761293ddcf997d1ee31ddbe
8192 6a294304c2655bc8a71c6b8c12e3319091f28010
8192 57553065db8ef56fa66b319e2ac94623a8f5f134
8192 d837ec08fb0e610d68075a514e20857d05042832
8192 0d5bc20788b75fc3ed112d2c8496f8f64e8bcae9
8192 83367b98b62d78166ef957d45b4a3533c91bd1d9

2 个答案:

答案 0 :(得分:2)

这很有效,而且很快

https://github.com/phpseclib/phpseclib

require_once 'Net/SFTP.php';

$sftp = new Net_SFTP($host);
    if (!$sftp->login('root', 'password') {
    exit('Login Failed');
}

$sftp->get('remote_file.ext', 'local_file.ext');

答案 1 :(得分:0)

您可以尝试将ssh2_scp_recv()包装器与ssh2.sftp://一起使用,而不是使用fopen()。这应该允许您以块的形式读取文件,这样就不会占用太多内存。

$connection = ssh2_connect('your.server.tld', 22);
ssh2_auth_password($connection, 'username', 'password');

$sftp = ssh2_sftp($connection);

$remote = fopen("ssh2.sftp://$sftp/path/to/file", 'rb');
$local = fopen('/path/to/file', 'w');

while(!feof($remote)){
    fwrite($local, fread($remote, 8192));
}

fclose($local);
fclose($remote);

免责声明:我没有对此进行过测试,但它看起来应该有效。

来源: