2011-03-22 30 views
9

Quiero dividir archivos enormes (para ser específicos, archivos tar.gz) en varias partes del código php. La razón principal para hacer esto es el límite de 2 gb de php en el sistema de 32 bits.Dividir archivos grandes usando PHP

SO Quiero dividir archivos grandes en varias partes y procesar cada parte por separado.

¿Esto es posible? Si es así, ¿cómo?

+1

Esta cuenta no es una tarea para PHP. ¿En qué sistema operativo estás –

+4

'split -b 2048 m file.tar.gz pieces' using' exec() '? – alex

+0

@alex Muy interesante .... –

Respuesta

0
  • Si desea dividir archivos que se ya en el servidor, puede hacerlo (basta con utilizar las funciones del archivo fread, fwrite, fopen, fseek para leer/escribir parte del archivo).
  • Si desea archivos divididos que se cargan desde el cliente , me temo que no puede.
1

PHP en sí podría no ser capaz de ... Si usted puede encontrar la manera de hacer esto desde la línea de comandos de sus computadoras, Usted debe ser capaz de ejecutar estos comandos a continuación, utilizando exec();

+0

ejecutivo puede estar deshabilitado para muchos hosts compartidos, por lo que no funcionará para mí – Mihir

0

Este probablemente sería posible en php, pero php fue desarrollado para el desarrollo web e intentar con toda esta operación en una solicitud dará como resultado que la solicitud agote el tiempo de espera.

Sin embargo, podría utilizar otro idioma como java o C# y crear un proceso en segundo plano que pueda notificar desde php para realizar la operación. O incluso ejecutar desde php, dependiendo de su configuración de seguridad en el host.

8

Mi comentario fue votado dos veces, así que tal vez mi conjetura estaba en algo: P

Si en un entorno Unix, intente esto ...

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

split

Su piec ES deberían ser pieces1, pieces2, etc.

Se puede obtener el número de piezas que resulta fácilmente mediante el uso stat() en PHP para obtener el tamaño del archivo y luego hacer la matemática simple (int) ($stat['size']/2048*1024*1024) (creo).

+0

Muy interesante ... definitivamente vale la pena buscar más en ... +1 para el concepto –

8

Un método simple (si se utiliza un servidor basado en Linux) es utilizar el comando exec y ejecutar el comando split:

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

Vea aquí para más detalles: http://www.computerhope.com/unix/usplit.htm

o puede utilizar: http://www.computerhope.com/unix/ucsplit.htm

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

PHP se ejecuta dentro de un único subproceso y la única manera de aumentar este conteo de subprocesos es crear un proceso secundario usando los comandos fork.

Esto no es adecuado para los recursos. Lo que sugeriría es buscar en un lenguaje que pueda hacerlo de manera rápida y efectiva. Sugeriría usar node.js.

Simplemente instale el nodo en el servidor y luego cree un pequeño script, llamado node_split por ejemplo, que puede hacer el trabajo por sí mismo.

Pero lo hago fuertemente aconsejo que no utilice PHP para este trabajo, pero use exec para permitir que el sistema operativo del host lo haga.

+0

ejecutivo puede estar deshabilitado para muchos hosts compartidos, por lo que no funcionará para mí – Mihir

+0

era mi suposición de que si él estaba en alojamiento compartido no tendría tal gran archivo en el servidor. – RobertPitt

1
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); 
} 
1
$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); 
0

Splits se nombran como 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; 
} 
?> 
Cuestiones relacionadas