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 ?
Asked
Active
Viewed 392 times
0
-
I don't have a solution for you, but many/most mail servers limit the entire message size, not just the attachment size, and many/most mail servers count the base64 encoded attachment, not the original file. A 2.92 MB file, when base64 encoded, will inflate to about 4 MB when base64 encoded, so that's probably your minimum target chunk. The message itself might have some overhead, too, so maybe drop that down to 2.5 MB for a decent safety margin. – Chris Haas Aug 19 '20 at 13:01
-
yeah as you said the whole Mail is not allowed to be over 4MB size. I am aware of base64 but yeah i will probably keep it at 2.5 MB chunks just to be sure. – Oliver Aug 19 '20 at 13:09
-
I'm assuming the person on the other end is able to reconstitute the file then, too? If so, I would use one of the methods here: https://stackoverflow.com/q/5391304/231316 – Chris Haas Aug 19 '20 at 13:13
-
Yeah. Ok i'll check it out, thanks for the help ! – Oliver Aug 19 '20 at 13:22
-
above link needs better answers, the split is abit thin `split --bytes 4M --numeric-suffixes --suffix-length=3 ./infile.ext ./infile.ext.` then to put back together `cat ./infile.ext.* > ./infile.ext` – Lawrence Cherone Aug 19 '20 at 13:22
1 Answers
1
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

ChrisCarcaud
- 46
- 2