Search code examples
phpsplitfopenfseek

Splitting and combining files


I have sort of a "beginning" of a solution. I wrote this function (Sorry about the spacings):

<?php
set_time_limit(0);

// Just to get the remote filesize

function checkFilesize($url, $user = "", $pw = ""){

 ob_start();

 $ch = curl_init($url);

 curl_setopt($ch, CURLOPT_HEADER, 1);

 curl_setopt($ch, CURLOPT_NOBODY, 1);

 if(!empty($user) && !empty($pw)){

  $headers = array('Authorization: Basic ' .  base64_encode("$user:$pw"));

  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

 }

 $ok = curl_exec($ch);

 curl_close($ch);

 $head = ob_get_contents();

 ob_end_clean();

 $regex = '/Content-Length:\s([0-9].+?)\s/';

 $count = preg_match($regex, $head, $matches);

 return isset($matches[1]) ? $matches[1] : "unknown";

}

// Split filesize to threads

function fileCutter($filesize,$threads){

 $calc = round($filesize / count($threads));

 $count = 0;

 foreach($threads as $thread){

  $rounds[$count] =  $calc;

  $count++;

 }

 $count = 0;

 foreach($rounds as $round){

  $set = $count + 1;

  if($count == 0){

   $from = 0;

  } else {

   $from = ($round * $count);

  }

  $cal = ($round * $set);

  $final[$count] = array('from'=>$from,'to'=>$cal);

  $count++;

 }

 // Correct the "Rounded" result

 $end = end($final);

 $differance = $filesize - $end['to'];

 if (strpos($differance,'-') !== false) {} else {$add = '+';}

 $end_result =  ($end['to'].$add.$differance);

 $value=eval("return ($end_result);");

 $end_id = end(array_keys($final));

 $final[$end_id]['to'] = $value;

 // Return the complete array with the corrected result

 return $final;

}

$threads = array(
 0=>'test',
 1=>'test',
 2=>'test',
 3=>'test',
 4=>'test',
 5=>'test',
);

$file  = 'http://www.example.com/file.zip';

$filesize = checkFilesize($file);

$cuts = fileCutter($filesize,$threads);

print_r($cuts);

?>

(Again, Sorry. :) )

It gives "directions" to split the file in specific bytes. I've tried to do something like so:

foreach($cuts as $cut){
$start = $cut['from'];
$finish = $cut['to'];
$f = fopen($file, "rb");
fseek($f, $start, SEEK_SET);
while(!(ftell($f) > $finish)){
  $data = fgetc($f);
}
fclose($f);

But it's going to a endless loop. What is the problem? or, is there another solution in PHP to split and combine files?


Solution

  • Instead of reading the file manually and byte-wise you could just use file_get_contents() with the according parameters $offset and $maxlen:

    //                             $incp  $ctx  $offset  $maxlen
    $data = file_get_contents($fn, FALSE, NULL, $start, $finish-$start);
    

    That'll do the seeking and cutting for you.