【问题标题】:Read or download 5kb of a file from FTP server in PHP or Python instead of downloading or reading whole file使用 PHP 或 Python 从 FTP 服务器读取或下载 5kb 文件,而不是下载或读取整个文件
【发布时间】:2026-02-11 16:25:01
【问题描述】:

我想从 FTP 服务器下载读取文件的一部分而不是下载整个文件,这只是为了查看 FTP 服务器中存在的数据是否正确。

我们有这么多客户端,FTP 服务器中的每个文件都可能是任意大小,所以我不想下载阅读完整的文件,我只想下载或阅读文件的一部分,假设我只想要 5kb 的文件,或者如果从文件中获取第 100 行。

我在 PHP 中有一个函数,如下所示,它完成了一半的工作,但对于较大的文件,它会失败。

function readByBytes($path)
{
    try
    {
        $handle = fopen($path, "rb");
        if ($handle) 
        {
            while (($buffer = fgets($handle, 4096)) !== false)
            {

            }
            if (!feof($handle))
            {
                echo "Error: unexpected fgets() fail\n";
            }
            fclose($handle);
        }
    }
    catch (Exception $e)
    {
        echo $e;
    }
}


$filename = "ftp://username:password@127.0.0.1/prod/clientfeed.csv";

$iterator = readByBytes($filename);

foreach ($iterator as $key => $iteration)
{
    /// if file read is 5kb or some 100 lines
    break;
}

有人可以用 PHP 或 Python 帮助我或指导我吗

出现以下警告错误

PHP Warning:  fopen(ftp://...@127.0.0.1/prod/clientfeed.csv): failed 
to open stream: FTP server reports 550 Could not get file size.
 in /var/www/html/newLpplugins/ftp_read_line_line.php on line 80
PHP Warning:  filesize(): stat failed for 
ftp://...@127.0.0.1/prod/clientfeed.csv in 
/var/www/html/newLpplugins/ftp_read_line_line.php on line 81
PHP Warning:  fread() expects parameter 1 to be resource, bool given 
in /var/www/html/newLpplugins/ftp_read_line_line.php on line 81
PHP Warning:  fclose() expects parameter 1 to be resource, bool given 
in /var/www/html/newLpplugins/ftp_read_line_line.php on line 82
PHP Warning:  
file_get_contents(ftp://...@127.0.0.1/prod/clientfeed.csv): failed to 
open stream: FTP server reports 550 Could not get file size.
in /var/www/html/newLpplugins/ftp_read_line_line.php on line 84

提前致谢。

【问题讨论】:

    标签: php python ftp


    【解决方案1】:

    如果您只想读取文件的一部分,则只需删除您的 while 循环并仅调用一次 fgets

    $buffer = fgets($handle, 4096);
    

    虽然如果文件是二进制文件或者如果你想读取固定数量的字节,你最好使用fread

    $buffer = fread($handle, 4096);
    

    尽管您的服务器与 PHP URL 包装器不兼容,请参阅:
    Getting "FTP server reports 550 Could not get file size." when using FTP URL in fopen
    而且 PHP 没有提供任何其他强大的替代方案来满足您的需求。


    虽然在 Python 中使用 ftplib 是可行的:

    ftp = FTP()
    ftp.connect(host, user, passwd)
    
    size = 4096
    
    cmd = "RETR {}".format(filename)
    f = BytesIO()
    aborted = False
    
    def gotdata(data):
        f.write(data)
        while (not aborted) and (f.tell() >= size):
            ftp.abort()
            aborted = True
    
    try:
        ftp.retrbinary(cmd, gotdata)
    except:
        # An exception when transfer is aborted is expected
        if not aborted:
            raise
    
    f.seek(0)
    

    代码基于我对以下内容的回答:
    Get files names inside a zip file on FTP server without downloading whole archive

    【讨论】:

      【解决方案2】:

      有一些方法可以在 python 中实现这一点。

      解决方案一:

      Paramkio - 在 python 中实现的 SSH V2 库 Paramiko 可以选择从远程位置的文件中读取 N 个字节

      sClient = ssh_client.open_sftp()
      remoteFileLocation = sftp_client.open('<filepath>')
      for line in remote_file:
          #dosomethinghere
      

      解决方案 2:

      这是一个临时解决方案。在此之前只是澄清如果您只是想知道文件中有内容,您可以使用它。

      使用 Python 子进程模块运行远程命令以获取文件大小。

              from subprocess import Popen, PIPE
              p = Popen(["du", "-sh", "filepath"], stdin=PIPE)
              output = p.communicate(msg.as_string())
      

      【讨论】:

      • 问题是关于 FTP,而不是 SFTP。