如何在PHP中对64位大型文件进行解码

时间:2009-05-20 14:58:54

标签: php memory base64

我的PHP Web应用程序有一个API,可以接收base64编码的合理大文件(最大32 MB)。目标是在我的文件系统上的某处写入这些文件。当然是解码的。这样做资源最少的方法是什么?

编辑:通过API接收文件意味着我的PHP应用中有32MB字符串,而不是磁盘上某处的32 MB源文件。我需要将该字符串解码为文件系统。

使用PHP自己的base64_decode()并没有削减它,因为它使用很多的内存,所以我一直在运行PHP的内存限制(我知道,我可以提高这个限制,但我不会让每个进程允许PHP使用256MB左右的感觉很好。

还有其他选择吗?我可以手动完成吗?或者将文件写入磁盘编码并调用一些外部命令?有什么想法吗?

3 个答案:

答案 0 :(得分:20)

虽然这有一个公认的答案,但我有不同的建议。

如果要从API中提取数据,则不应将整个有效内容存储在变量中。使用curl或其他HTTP提取程序,您可以自动将数据存储在文件中。

假设您通过简单的GET URL获取数据:

$url = 'http://www.example.com/myfile.base64';
$target = 'localfile.data';

$rhandle = fopen($url,'r');
stream_filter_append($rhandle, 'convert.base64-decode');

$whandle = fopen($target,'w');

stream_copy_to_stream($rhandle,$whandle);
fclose($rhandle);
fclose($whandle);

优点:

  • 应该更快(减少对巨大变量的复制)
  • 内存开销很小

如果你必须从临时变量中获取数据,我可以建议这种方法:

$data = 'your base64 data';
$target = 'localfile.data';

$whandle = fopen($target,'w');
stream_filter_append($whandle, 'convert.base64-decode',STREAM_FILTER_WRITE);

fwrite($whandle,$data);

fclose($whandle);

答案 1 :(得分:11)

以较小的块解码数据。 Base64数据的四个字符等于“Base256”数据的三个字节。

因此,您可以对每个1024个字符进行分组,并将它们解码为768个八位字节的二进制数据:

$chunkSize = 1024;
$src = fopen('base64.data', 'rb');
$dst = fopen('binary.data', 'wb');
while (!feof($src)) {
    fwrite($dst, base64_decode(fread($src, $chunkSize)));
}
fclose($dst);
fclose($src);

答案 2 :(得分:1)

传输 32Mb 字符串不是一个好主意。但是我有一个解决方案,可以接受从浏览器到应用程序服务器的任何大小的文件。算法: 客户

  1. Javascript:使用 FileReader 和 readAsDataURL() 从 INPUT 读取文件到 FILE 变量。
  2. 将 FILE 中的所有数据从开始到第一个“,”位置通过 max_upload_size/max_post_size php var 与 array_chunks 分割。
  3. 发送带有 UID、块号和块数量的块并等待响应,然后一个一个地发送另一个块。

服务器端 写入每个块直到最后一个。然后用流做 base64:

$src = fopen($source, 'r');
$trg = fopen($target, 'w');
stream_filter_append($src, 'convert.base64-decode');
stream_copy_to_stream($src, $trg);
fclose($src);
fclose($trg);

... 现在您的 base64 解码文件位于 $target 本地路径中。笔记!不能读写同一个文件,所以 $source 和 $target 必须不同。