使用 PHP 或 Python 从 FTP 服务器读取或下载 5kb 的文件,而不是下载或读取整个文件

Che*_*thu 2 php python ftp

我想从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;
}
Run Code Online (Sandbox Code Playgroud)

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

以下警告错误得到

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;
}
Run Code Online (Sandbox Code Playgroud)

提前致谢。

Mar*_*ryl 5

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

$buffer = fgets($handle, 4096);
Run Code Online (Sandbox Code Playgroud)

但是,如果文件是二进制文件,或者如果您想读取固定数量的字节,则最好使用fread.

$buffer = fread($handle, 4096);
Run Code Online (Sandbox Code Playgroud)

尽管您的服务器与 PHP URL 包装器不兼容,请参阅:
获取“FTP 服务器报告 550 无法获取文件大小”。在 fopen 中使用 FTP URL 时
,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)
Run Code Online (Sandbox Code Playgroud)

该代码基于我对以下问题的回答:
在 FTP 服务器上的 zip 文件中获取文件名,而无需下载整个存档