2

我有一个系统,在将文件从电子邮件文件中剥离后,以 base 64 编码将文件保存到服务器硬盘。

我想再次将文件更改为原始格式,我该如何在 php 中做到这一点?

这就是我尝试保存文件的方式,但这似乎没有创建有效文件:

$start = $part['starting-pos-body'];
$end = $part['ending-pos-body'];
$len = $end-$start;
$written = 0;
$write = 2028;
$body = '';
while ($start <= $end) {
 fseek($this->stream, $start, SEEK_SET);
 $my = fread($this->stream, $write);
 fwrite($temp_fp, base64_decode($my));
 $start += $write;
}
fclose($temp_fp);
4

3 回答 3

3

@traylz 清楚地说明了为什么它可能会在不应该失败的情况下失败。但是,base64_decode()即使是大图像也可能会失败。我已经很好地处理了 6 到 7 MB 的文件,我还没有超过这个大小,所以对我来说它应该很简单:

$dir = dirname(__FILE__);
// get the base64 encoded file and decode it
$o_en = file_get_contents($dir . '/base64.txt');
$d = base64_decode($o_en);

// put decoded string into tmp file
file_put_contents($dir . '/base64_d', $d);

// get mime type (note: mime_content_type() is deprecated in favour
// for fileinfo functions)
$mime = str_replace('image/', '.', mime_content_type($dir . '/base64_d'));
rename($dir . '/base64_d', $dir . '/base64_d' . $mime);

如果以下失败尝试添加chunk_split()功能到解码操作:

$d = base64_decode(chunk_split($o_en));

那么我在说什么...忘记循环,除非需要它...如果您不信任 php 的 mime 检测,请保留原始文件扩展名。如果处理大文件,请chunk_split()使用操作。base64_decode()

注意:所有理论都未经检验

编辑:对于很可能会冻结的大文件file_get_contents(),读入您需要的内容,输出到文件,因此使用的 RAM 很少:

$chunkSize = 1024;
$src = fopen('base64.txt', 'rb');
$dst = fopen('binary.mime', 'wb');
while (!feof($src)) {
    fwrite($dst, base64_decode(fread($src, $chunkSize)));
}
于 2013-10-22T07:44:42.087 回答
1

您的问题是您读取了 2028 个块,在读取块后检查 start<=end,因此您读取超出了结束指针,您应该检查 < insead of <= (以避免读取 0 字节)

此外,您不需要每次迭代都 fseek ,因为 fread 从当前位置读取。您可以将 fssek 排除在循环之外(在 while 之前)。为什么是 2028 顺便说一句?试试这个:

fseek($this->stream, $start, SEEK_SET);
while ($start < $end) {
    $write = min($end-$start,2048);
    $my = fread($this->stream, $write);
    fwrite($temp_fp, base64_decode($my));
    $start += $write;
}
fclose($temp_fp);
于 2013-10-22T07:07:53.267 回答
1

谢谢大家的帮助,最后我得到了:

shell_exec('/usr/bin/base64 -d '.$temp_file.' > '.$temp_file.'_s');
于 2013-10-22T11:33:36.083 回答