DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

File/Folder Joiner/unjoiner

11.17.2008
| 2949 views |
  • submit to reddit
        Joins/unjoins files/folders into one unique file.

//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com

class Joiner{
	var $header;

	function Joiner(){
		$this->header = strlen(pack('CVV', 0, 0, 0));
	}

	function join($dir, $out, $recursive = true){
		if(!$out = fopen($out, 'wb'))
			die('erro ao criar o arquivo');

		for($s = DIRECTORY_SEPARATOR, $stack = array($dir); $dir = array_pop($stack);){
			if(!($handle = @dir($dir)))
				continue;
			fwrite($out, pack('CVV', 1, strlen($dir), 0) . $dir);
			while(false !== $item = $handle->read())
				if($item != '.' && $item != '..'){
					$path = $handle->path . $s . $item;
					if(!is_dir($path) && ($f = fopen($path, 'rb'))){
						fwrite($out, pack('CVV', 0, strlen($item), $size = filesize($path)) . $item);
						$size && fwrite($out, fread($f, $size));
						fclose($f);
					}
					elseif($recursive)
						array_push($stack, $path);
				}
			$handle->close();
		}
		fclose($out);
	}

	function unjoin($dir, $in){
		$_ = getcwd();
		$s = DIRECTORY_SEPARATOR;
		if(!$in = fopen($in, 'rb'))
			die('erro ao abrir o arquivo');
		$dir && chdir($dir) && $dir = getcwd() . $s;
		$curdir = '';
		while($h = fread($in, $this->header)){
			$h = unpack('Cdir/Vname/Vsize', $h);
			$name = fread($in, $h['name']);
			if($h['dir']){
				if(!is_dir($curdir = $dir . $name))
					mkdir($curdir, 0777);
				chdir($curdir);
			}
			else{
				$f = fopen($file = $name, 'wb');
				$h['size'] && fwrite($f, fread($in, $h['size']));
				fclose($f);
				chmod($file, 0777);
			}
		}
		fclose($in);
		chdir($_);
	}
}