【问题标题】:Split big files using PHP使用 PHP 拆分大文件
【发布时间】:2011-07-20 11:07:38
【问题描述】:

我想从 php 代码中拆分多个部分的大文件(具体来说是 tar.gz 文件)。这样做的主要原因是 php 在 32 位系统上的 2gb 限制。

所以我想将大文件分成多个部分并分别处理每个部分。

这可能吗?如果是,怎么做?

【问题讨论】:

  • 不是 PHP 的任务。您使用的是什么操作系统?
  • split -b 2048 m file.tar.gz pieces 使用 exec() ?
  • @alex 很有趣....

标签: php file split


【解决方案1】:

我的评论被投票了两次,所以也许我的猜测是:P

如果在 unix 环境中,试试这个...

exec('split -d -b 2048m file.tar.gz pieces');

split

您的作品应该是pieces1pieces2 等。

您可以通过在 PHP 中使用 stat() 来获取文件大小,然后进行简单的数学运算 (int) ($stat['size'] / 2048*1024*1024)(我认为),轻松获得结果片段的数量。

【讨论】:

  • 非常有趣.. 绝对值得进一步研究... +1 的概念
【解决方案2】:

一个简单的方法(如果使用基于 Linux 的服务器)是使用 exec 命令并运行 split 命令:

exec('split Large.tar.gz -b 4096k SmallParts'); // 4MB parts
/*    |     |            |      | |
      |     |            |______| |
      App   |                 |   |_____________
            The source file   |                 |
                              The split size    Out Filename
*/

更多详情请看这里:http://www.computerhope.com/unix/usplit.htm

或者你可以使用:http://www.computerhope.com/unix/ucsplit.htm

exec('csplit -k -s -f part_ -n 3 LargeFile.tar.gz');

PHP 在单个线程中运行,增加此线程数的唯一方法是使用 fork 命令创建子进程。

这对资源不友好。我的建议是研究一种可以快速有效地做到这一点的语言。我建议使用 node.js。

只需在服务器上安装节点,然后创建一个小脚本,例如称为node_split,它可以为您自己完成这项工作。

但我确实强烈建议您不要使用 PHP 来完成这项工作,而是使用 exec 来允许主机操作系统执行此操作。

【讨论】:

  • exec 可能对许多共享主机被禁用,所以对我不起作用
  • 我的假设是,如果他在共享主机上,他的服务器上不会有这么大的文件。
【解决方案3】:

【讨论】:

  • 我认为这不起作用,因为 32 位系统上的 PHP 甚至无法打开大于 2 gb 的文件
【解决方案4】:

PHP 本身可能无法... 如果您可以从计算机的命令行中弄清楚如何执行此操作, 然后您应该能够使用exec(); 执行这些命令

【讨论】:

  • exec 可能对许多共享主机被禁用,因此对我不起作用
【解决方案5】:
function split_file($source, $targetpath='/split/', $lines=1000){

    $i=0;
    $j=1;
    $date = date("m-d-y");
    $buffer='';

    $handle = fopen ($_SERVER['DOCUMENT_ROOT'].$source, "r");

    while (!feof ($handle)) {
        $buffer .= fgets($handle, 4096);
        $i++;
        if ($i >= $lines) {
            $fname = $_SERVER['DOCUMENT_ROOT'].$targetpath."part_".$date.$j.".txt";

                 $fhandle = fopen($fname, "w") or die($php_errormsg);

            if (!$fhandle) {
                echo "Cannot open file ($fname)";
                //exit;
            }


            if (!fwrite($fhandle, $buffer)) {
                echo "Cannot write to file ($fname)";
                //exit;
            }
            fclose($fhandle);
            $j++;
            $buffer='';
            $i=0;
            $line+=10; // add 10 to $lines after each iteration. Modify this line as required
        }
    }
    fclose ($handle);
}

【讨论】:

    【解决方案6】:
    $handle = fopen('source/file/path','r'); 
            $f = 1; //new file number
            while(!feof($handle))
            {
                $newfile = fopen('newfile/path/'.$f.'.txt','w'); //create new file to write to with file number
                for($i = 1; $i <= 5000; $i++) //for 5000 lines
                {
                    $import = fgets($handle);
                    //print_r($import);
                    fwrite($newfile,$import);
                    if(feof($handle))
                    {break;} //If file ends, break loop
                }
                fclose($newfile);
                $f++; //Increment newfile number
            }
            fclose($handle);
    

    【讨论】:

      【解决方案7】:
      • 如果你想分割文件 已经在服务器上,你可以做到 (只需使用文件函数 fread, fopen, fwrite, fseek 读/写 文件的一部分)。
      • 如果你想 拆分从上传的文件 客户,恐怕你不能。

      【讨论】:

        【解决方案8】:

        这在 php 中可能是可能的,但 php 是为 Web 开发而构建的,尝试在一个请求中完成整个操作将导致请求超时。

        但是,您可以使用其他语言(如 java 或 c#)并构建一个后台进程,您可以从 php 通知该进程以执行操作。甚至可以从 php 运行,具体取决于您在主机上的安全设置。

        【讨论】:

          【解决方案9】:

          拆分被命名为 filename.part0 filename.part1 ...

          <?php
          function fsplit($file,$buffer=1024){
              //open file to read
              $file_handle = fopen($file,'r');
              //get file size
              $file_size = filesize($file);
              //no of parts to split
              $parts = $file_size / $buffer;
          
              //store all the file names
              $file_parts = array();
          
              //path to write the final files
              $store_path = "splits/";
          
              //name of input file
              $file_name = basename($file);
          
              for($i=0;$i<$parts;$i++){
                  //read buffer sized amount from file
                  $file_part = fread($file_handle, $buffer);
                  //the filename of the part
                  $file_part_path = $store_path.$file_name.".part$i";
                  //open the new file [create it] to write
                  $file_new = fopen($file_part_path,'w+');
                  //write the part of file
                  fwrite($file_new, $file_part);
                  //add the name of the file to part list [optional]
                  array_push($file_parts, $file_part_path);
                  //close the part file handle
                  fclose($file_new);
              }    
              //close the main file handle
          
              fclose($file_handle);
              return $file_parts;
          }
          ?>
          

          【讨论】:

            猜你喜欢
            • 2021-01-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多