Reputation: 1
I want to split a file into multiple byte ranges, less than 4 MB, because the Mail Server doesn't allow Mails bigger than 4MB. I'm trying to find a solution in in PHP. I set up a upload session (https://learn.microsoft.com/en-us/graph/outlook-large-attachments?tabs=http#step-1-create-an-upload-session) but for that to work i need to split the Mails that are larger than 4MB into chunks. Any suggestions ?
Upvotes: 0
Views: 580
Reputation: 46
for years, a backup application has been working like this: collect the files in zip, split them into 2 Mb files, upload them to the server and then rebuild the origin ZIP files.
The chunk/glue file class class FileSplitter {
/**
* Chunk input file to smaller files
* @param type $input_filename
* @param type $chunksize
* @param type $destpath
* @return string
* @throws Exception
*/
static public function writeChunks($input_filename, $chunksize, $destpath = '') {
$out_files = array();
//Input file exists
if (!file_exists($input_filename) || !is_readable($input_filename)) {
throw new Exception('File not exists ' . $input_filename);
}
//Destination chunks
$chunk_number = 1;
$info = pathinfo($input_filename);
if (!empty($destpath)) {
$output_dir = rtrim($destpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
} else {
$output_dir = '';
}
$output_filename = $output_dir . $info['filename'] . '.' . str_pad($chunk_number, 3, '0', STR_PAD_LEFT);
$rh = fopen($input_filename, 'rb');
$wh = fopen($output_filename, 'wb');
$out_files[] = $output_filename;
if ($rh!=false && $wh!=false) {
while (!feof($rh)) {
$buf = fread($rh, 1024);
fwrite($wh, $buf);
if (ftell($wh) >= $chunksize) {
fclose($wh);
$chunk_number++;
$output_filename = $output_dir . $info['filename'] . '.' . str_pad($chunk_number, 3, '0', STR_PAD_LEFT);
$out_files[] = $output_filename;
$wh = fopen($output_filename, 'wb');
if ($wh==false) {
fclose($rh);
throw new Exception('output file open error ');
}
}
}
fclose($wh);
fclose($rh);
} else {
throw new Exception('Input or output file open error ');
}
return $out_files;
}
static public function glueChunks($chunk_list, $output_filename) {
$wh = fopen($output_filename, 'wb');
foreach ($chunk_list as $chunk_file) {
$rh = fopen($chunk_file, 'rb');
if ($rh) {
while (!feof($rh)) {
$buf = fread($rh, 1024);
fwrite($wh, $buf);
}
fclose($rh);
}
}
fclose($wh);
}
}
How to use
$CHUNK_SIZE = 1024 * 1024 * 2;
//split into chunks
$n_chunks = FileSplitter::writeChunks(realpath($n_Backup['archive']), $CHUNK_SIZE, sys_get_temp_dir());
//Assemble to one file
$n_chunks = FileSplitter::writeChunks($n_chunks,'big_file.zip');
Maybe you can adapt source code to Mail Server
Upvotes: 1