首页 \ 问答 \ PHP - 使用FTP合并文件(PHP - Merging files with FTP)

PHP - 使用FTP合并文件(PHP - Merging files with FTP)

所以,我正在尝试使用FTP将文件从本地服务器复制到远程服务器。 问题是,我需要以大块的方式做到这一点。

到目前为止,根据我的研究,通过在我的本地服务器上创建两个文件来看起来可能是最简单的:要复制的文件和一个保存当前块的小型临时文件。 然后,我应该简单地将该块与远程文件合并。

问题是,我在添加文件时遇到问题。 我无法弄清楚ftp://协议是如何工作的,我无法找到有关如何使用cURL的全面解释。 我发现的最接近的是这个 ,但我无法让它发挥作用。

以下是我到目前为止所写的内容。 我已经对它进行了评论,因此您可以浏览它以获得想法,并查看我遇到的问题 - 代码并不复杂。 你有什么建议我做的? 如何使用FTP将本地服务器上的文件附加到远程服务器上的文件中?

<?php

// FTP credentials
$server = HIDDEN;
$username = HIDDEN;
$password = HIDDEN;

// Connect to FTP
$connection = ftp_connect($server) or die("Failed to connect to <b>$server</b>.");

// Login to FTP
if (!@ftp_login($connection, $username, $password))
{
    echo "Failed to login to <b>$server</b> as <b>$username</b>.";
}

// Destination file (where the copied file should go)
$destination = 'final.txt';

// The file on my server that we're copying (in chunks) to $destination.
$read = 'readme.txt';

// Current chunk of $read.
$temp = 'temp.tmp';

// If the file we're trying to copy exists...
if (file_exists($read))
{
    // Set a chunk size (this is tiny, but I'm testing
    // with tiny files just to make sure it works)
    $chunk_size = 4;

    // For reading through the file we want to copy to the FTP server.
    $read_handle = fopen($read, 'r');

    // For writing the chunk to its own file.
    $temp_handle = fopen($temp, 'w+');

    // Loop through $read until we reach the end of the file.
    while (!feof($read_handle))
    {
        // Read a chunk of the file we're copying.
        $chunk = fread($read_handle, $chunk_size);

        // Write that chunk to its own file.
        fwrite($temp_handle, $chunk);

        ////////////////////////////////////////////
        ////                                    ////
        ////       NOW WHAT?? HOW DO I          ////
        ////       WRITE / APPEND THAT          ////
        ////       CHUNK TO $destination?       ////
        ////                                    ////
        ////////////////////////////////////////////
    }
}

fclose($read_handle);
fclose($temp_handle);
ftp_close($ftp_connect);
?>

So, I'm trying to copy a file from my local server to a remote server with FTP. The problem is, I need to do this in chunks.

Thus far, based on my research, it looks like it will probably be easiest to do this by making two files on my local server: the file to be copied, and a small, temporary file that holds the current chunk. Then, I should simply merge that chunk with the remote file.

The problem is, I'm having trouble appending files. I can't figure out how the ftp:// protocol works, and I can't find a comprehensive explanation on how to do it with cURL. The closest I've found is this, but I couldn't get it working.

Below is what I've written up so far. I've commented it so you can just skim through it to get the idea, and see where I'm stuck--the code isn't complicated. What do you recommend I do? How do I append a file on my local server a file on a remote server with FTP?

<?php

// FTP credentials
$server = HIDDEN;
$username = HIDDEN;
$password = HIDDEN;

// Connect to FTP
$connection = ftp_connect($server) or die("Failed to connect to <b>$server</b>.");

// Login to FTP
if (!@ftp_login($connection, $username, $password))
{
    echo "Failed to login to <b>$server</b> as <b>$username</b>.";
}

// Destination file (where the copied file should go)
$destination = 'final.txt';

// The file on my server that we're copying (in chunks) to $destination.
$read = 'readme.txt';

// Current chunk of $read.
$temp = 'temp.tmp';

// If the file we're trying to copy exists...
if (file_exists($read))
{
    // Set a chunk size (this is tiny, but I'm testing
    // with tiny files just to make sure it works)
    $chunk_size = 4;

    // For reading through the file we want to copy to the FTP server.
    $read_handle = fopen($read, 'r');

    // For writing the chunk to its own file.
    $temp_handle = fopen($temp, 'w+');

    // Loop through $read until we reach the end of the file.
    while (!feof($read_handle))
    {
        // Read a chunk of the file we're copying.
        $chunk = fread($read_handle, $chunk_size);

        // Write that chunk to its own file.
        fwrite($temp_handle, $chunk);

        ////////////////////////////////////////////
        ////                                    ////
        ////       NOW WHAT?? HOW DO I          ////
        ////       WRITE / APPEND THAT          ////
        ////       CHUNK TO $destination?       ////
        ////                                    ////
        ////////////////////////////////////////////
    }
}

fclose($read_handle);
fclose($temp_handle);
ftp_close($ftp_connect);
?>

原文:https://stackoverflow.com/questions/11267057
更新时间:2022-12-17 21:12

最满意答案

需要注意的关键是imap懒惰的 - 除非你实际使用了生成的迭代器,否则它不会做任何工作:

>>> map(lamda x: x, xrange(0, 2))
[0, 1]

>>> from itertools import imap
>>> imap(lamda x: x, xrange(0, 2))
<generator object at 0xsome-address>

# Consume the resulting iterator
>>> list(imap(lamda x: x, xrange(0, 2)))
[0, 1]

multiprocessinggevent imap遵循相同的规则。


The key thing to note is that imap is lazy - it does not do any work until you actually consume the resulting iterator:

>>> map(lamda x: x, xrange(0, 2))
[0, 1]

>>> from itertools import imap
>>> imap(lamda x: x, xrange(0, 2))
<generator object at 0xsome-address>

# Consume the resulting iterator
>>> list(imap(lamda x: x, xrange(0, 2)))
[0, 1]

imap in multiprocessing and gevent adheres to the same rules.

相关问答

更多
  • tqdm不适用于map因为map阻塞; 它等待所有结果,然后将它们作为list返回。 在执行循环时,唯一要取得的进展是循环中发生的事情 - 并行阶段已经完成。 imap不会阻塞,因为它只返回一个迭代器,也就是说你可以要求下一个结果,下一个结果和下一个结果。 只有当你这样做时,通过循环,下一个结果会一个接一个地等待。 它作为迭代器的结果意味着一旦所有结果都被消耗完(循环结束),它就是空的。 因此,没有什么可以放在list 。 如果你想保留结果,例如你可以在循环中追加每个结果,或者将代码更改为: res_p = ...
  • imap / imap_unordered和map / map_async之间有两个关键的区别: 他们消耗你传递给他们的迭代的方式。 他们将结果返回给你的方式。 map通过将iterable转换为列表(假设它不是列表)消耗您的迭代,将其分解成块,并将这些块发送到Pool的工作进程。 将迭代打破成块可以比在每个进程之间的迭代中每个项目一次传递每个项目更好 - 特别是如果iterable大的话。 然而,将iterable转换成列表以便块可以具有非常高的内存成本,因为整个列表将需要保存在内存中。 imap不会将您 ...
  • 由于处理速度很快,但写入速度很慢,这听起来像是您的问题是I / O限制。 因此,使用多处理可能没有多少好处。 但是,可以剥离data块,处理块并等待数据写入之后才剥离另一个块: import itertools as IT if __name__ == "__main__": data = records(100) with Pool(2) as pool: chunksize = ... for chunk in iter(lambda: list(IT.i ...
  • 这取决于您如何定义池。 正如你在你的例子中所做的那样,你的(2)发生了。 初始化池后,您的线程或进程将依赖于池启动(在Pool__init__() - 无需为此提交任务)并且他们坐在那里等待任务。 当任务到达并执行时,线程或进程不会退出,它们只会返回等待状态,等待更多工作的到来。 但是,您可以使用不同的方式定义它。 您可以将maxtasksperchild参数添加到池中。 一旦工人完成了这么多任务,它就会退出,并立即启动一个新工人(不需要先给它任务,一旦工人退出就会启动它)。 这在Pool类Pool._ma ...
  • 首先注意到这是有效的: import multiprocessing as mp import multiprocessing.util as util pool=mp.Pool(1) print list(pool.imap(abs, range(3))) 不同之处在于,当对pool.imap()的调用结束时, pool没有完成。 相反, print(list(mp.Pool(1).imap(abs, range(3)))) 导致Pool实例在imap调用结束后不久结束。 缺少引用会导致调用Final ...
  • 我发现了这个问题。 map()的第二个参数应该是一个可迭代的,在我的例子中是一个包含 单个对象 的列表 。 哪里不对 ? 这: [drain_queue()] ,它生成一个列表,其中包含一个对象。 在这种情况下,代码 with multiprocessing.Pool(4) as process_pool: results = process_pool.map(do_stuff, [drain_queue()]) 强制multiprocessing.Pool.map将单个对象“分配”到单个进程,即 ...
  • 这是IDLE的问题,您正在使用它来运行代码。 IDLE对终端进行相当基本的仿真,以处理您在其中运行的程序的输出。 它虽然无法处理子进程,所以虽然它们在后台运行得很好,但你永远不会看到它们的输出。 最简单的解决方法是从命令行运行代码。 另一种方法可能是使用更复杂的IDE。 在Python维基上列出了一堆它们,虽然我不确定哪些有更好的终端仿真用于多处理输出。 This is an issue with IDLE, which you're using to run your code. IDLE does a ...
  • 为避免“意外”问题,请避免使用全局变量。 要使用调用plotFrame内置map重现您的第一个代码示例: def plotFrame(n): a = data[n, :] do_something_with(a) 使用multiprocessing.Pool.map ,首先要处理全局data 。 如果do_something_with(a)也使用一些全局数据,那么它也应该被更改。 要了解如何将numpy数组传递给子进程,请参阅在共享内存中使用numpy数组进行多处理 。 如果您不需要修改数 ...
  • 需要注意的关键是imap是懒惰的 - 除非你实际使用了生成的迭代器,否则它不会做任何工作: >>> map(lamda x: x, xrange(0, 2)) [0, 1] >>> from itertools import imap >>> imap(lamda x: x, xrange(0, 2)) # Consume the resulting iterator >>> list(imap(lamda x: x, xrang ...
  • map函数的第一个参数应该是一个函数,它应该接受一个参数。 它是强制性的,因为迭代将传递,因为第二个参数将被迭代,并且值将在每次迭代中逐个传递给函数。 所以,你最好的办法是重新定义f接受一个参数并忽略它,或者用一个参数写一个包装函数,忽略参数并返回f的返回值,就像这样 from multiprocessing import Pool def f(): # no argument return 1 def throw_away_function(_): return f() print ...

相关文章

更多

最新问答

更多
  • 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
  • 如何通过引用返回对象?(How is returning an object by reference possible?)
  • 矩阵如何存储在内存中?(How are matrices stored in memory?)
  • 每个请求的Java新会话?(Java New Session For Each Request?)
  • css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
  • 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
  • xcode语法颜色编码解释?(xcode syntax color coding explained?)
  • 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
  • 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
  • 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
  • 西安哪有PLC可控制编程的培训
  • 在Entity Framework中选择基类(Select base class in Entity Framework)
  • 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
  • 电脑二级VF有什么用
  • Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
  • 金华英语角.
  • 手机软件如何制作
  • 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
  • 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
  • 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
  • Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
  • 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
  • python的访问器方法有哪些
  • DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
  • 在Ruby中对组合进行排序(Sorting a combination in Ruby)
  • 网站开发的流程?
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。