使用 ssh2.sftp 和 fread 未完全下载 SFTP 文件

SFTP file is not downloaded completelly with ssh2.sftp and fread

我正在为需要 SFTP 来查看日志的独立系统下载日志文件。我能够查看服务器上可用的日志文件并下载它们。我的问题是下载似乎停在 2K,在大多数情况下,这只是日志文件的前 10 行。这些文件应包含数千行,因为它们是对系统所做更改的每日日志。

我在两个单独的文件中完成了此操作,一个将所有文件加载到一个页面上,用户可以在该页面上 select 可用的日志文件,然后单击 link 查看内容浏览器:

$ftp_server = "IP of Server";
$ftp_user_name = "USERNAME";
$ftp_user_pass = "PASSWORD";

$connection = ssh2_connect($ftp_server, 22); 
ssh2_auth_password($connection,$ftp_user_name, $ftp_user_pass);
$sftp = ssh2_sftp($connection); 

$dh = opendir("ssh2.sftp://$sftp//EMSftp/audit_files/"); 

while (($file = readdir($dh)) !== false) { 
    if ($file != '.' && $file != '..'){
        if (strpos($file,"2017-04")){
            echo '/EMSftp/audit_files/'.$file.' | <a href="open_file_curl.php?file='.$file.'" target="_blank">curl</a>
                                                | <a href="open_file.php?file='.$file.'" target="_blank">view</a><br>';
        }
    }
} 

closedir($dh);

我尝试使用 sftp 和 ssh2 以两种不同的方式下载文件:

$file = $_GET['file'];
$local_file = "/var/www/uploads/logs/$file";

if (!file_exists($local_file)){
    $connection = ssh2_connect($ftp_server, 22); 
    ssh2_auth_password($connection,$ftp_user_name, $ftp_user_pass);
    $sftp = ssh2_sftp($connection); 

    $stream = @fopen("ssh2.sftp://$sftp//EMSftp/audit_files/$file", 'r');

    if (! $stream)
        throw new Exception("Could not open file: $remote_file");
    $contents = fread($stream, filesize("ssh2.sftp://$sftp//EMSftp/audit_files/$file"));            
    file_put_contents ($local_file, $contents);
    @fclose($stream);
}

echo '<pre>';
echo file_get_contents($local_file);
echo '</pre>';

并且还尝试使用 curl 来完成此操作。这只会创建一个空白文件。不确定这里缺少什么。无法将文件内容添加到文件中。

$file = $_GET['file'];

$local_file = "/var/www/uploads/logs/$file";

fopen($local_file, 'w+');
chmod($local_file, 0777);

$remote = "sftp://$ftp_user_name:$ftp_user_pass@$ftp_server//EMSftp/audit_files/$file";

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $remote);
curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
curl_setopt($curl, CURLOPT_USERPWD, "$ftp_user_name:$ftp_user_pass");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$somecontent = curl_exec($curl);
if (is_writable($local_file)) {

    if (!$handle = fopen($local_file, 'a')) {
         echo "Cannot open file ($local_file)";
         exit;
    }

    if (fwrite($handle, $somecontent) === FALSE) {
        echo "Cannot write to file ($local_file)";
        exit;
    }

    echo "Success, wrote ($somecontent) to file ($local_file)";

    fclose($handle);

} else {
    echo "The file $local_file is not writable";
}
curl_close($curl);

不确定我遗漏了什么。想知道是否有与我忽略的此过程相关的超时。有帮助吗?

这是错误的:

$contents = fread($stream, filesize("ssh2.sftp://$sftp//EMSftp/audit_files/$file"));

它不能保证您会读取整个文件。

作为documented:

fread() reads up to length bytes


如果日志大小合理,使用简单 file_get_contents:

$contents = file_get_contents("ssh2.sftp://$sftp//EMSftp/audit_files/$file");

如果没有,循环读取文件块:

$stream = @fopen("ssh2.sftp://$sftp//EMSftp/audit_files/$file", 'r');

while (!feof($stream))
{
    $chunk = fread($stream, 8192);
    // write/append chunk to a local file
}

@fclose($stream);