首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >下载ZipArchive OutOfMemory

下载ZipArchive OutOfMemory
EN

Stack Overflow用户
提问于 2018-09-25 09:18:45
回答 3查看 415关注 0票数 0

在我的heroku应用程序上下载文件时,我有一个问题。我有一个基本的PHP,它允许我们有128 to的内存限制。

我的错误如下:

(1/1) OutOfMemoryException错误:允许内存大小为134217728字节(试图分配77709312字节)

好的,我明白了,但奇怪的是,77709312bytes只有74 Ok。

那怎么了?

这是我下载操作的代码:

代码语言:javascript
复制
/**
 * @Route("/templates/{id}/download", name="api_templates_download", requirements={"id"="\d+"})
 * @Method({"GET"})
 * @param \Symfony\Component\HttpFoundation\Request $request
 * @return \Symfony\Component\HttpFoundation\Response
 * @throws \Exception
 */
public function downloadTemplate(Request $request)
{
    $id = $request->get('id');

    try {
        $template = $this->service->getTemplate($id, $this->helper->getUser());
        $archive = $this->service->downloadTemplate($template);
        $response = new Response(file_get_contents($archive));
        $response->headers->set('Content-Type', 'application/zip');
        $response->headers->set('Content-Disposition', 'attachment;filename="' . $archive . '"');
        $response->headers->set('Content-length', filesize($archive));

        return $response;
    } catch (\Exception $e) {
        $response = new Response(json_encode($e->getMessage()), 401);
        $response->headers->set('Content-Type', 'application/json');
        return $response;
    }
}

而控制器中调用的方法downloadTemplate

代码语言:javascript
复制
/**
 * @tests Need to tests about performance - do this in September with real server
 * @param \App\Domain\Dollycast\Template\Entity\Template $template
 * @return string
 */
public function downloadTemplate(Template $template)
{
    $zip = new \ZipArchive();
    $zipName = self::ZIPDIR . $template->getName() . '.zip';

    $zip->open($zipName, \ZipArchive::CREATE);

    $finder = new Finder();
    $finder->files()->in(self::WORKDIR . $template->getName());

    $zip->addEmptyDir($template->getName());
    /** @var SplFileInfo $file */
    foreach ($finder as $file) {
        // Rename the full path to the relative Path
        $zip->addFile(
            self::WORKDIR . $template->getName() . DIRECTORY_SEPARATOR . $file->getRelativePathname(),
            $template->getName() . DIRECTORY_SEPARATOR . $file->getRelativePathname()
        );
    }

    $zip->close();

    return $zipName;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-09-25 13:50:51

file_get_contents将文件加载到内存中,当我将其放入Response对象时,这将有效地将所有内容从内存复制到输出缓冲区。这就是为什么在74MB附近的存档将导致由于双重工作导致的128米配置(74*2)错误的Out of memory

此时,我无法使用readfile()来解决这个问题,因为我的行为与我的需要有很大的不同。但是readfile()将在不使用两次内存的情况下打开并输出到缓冲区。

编辑:我发现的最佳选择是使用Symfony3.2wc中的BinaryFileResponse对象有效地处理响应流。

票数 1
EN

Stack Overflow用户

发布于 2018-09-25 10:05:19

(1/1) OutOfMemoryException错误:允许内存大小为134217728字节(试图分配77709312字节)

此时,proccess尝试分配它已经分配的77709312字节内存,可以用函数memory_get_usage()检查这些内存。在您的例子中,这必须大于(134217728 - 77709312 =) 56508416字节。

如果在创建zip文件期间引发异常,则可以尝试使用外部工具创建zip文件。有点像

(“tar -zcvf archive.tar.gz /archive.tar.gz/tozip”);

否则,试着找出何时抛出此异常,尝试释放所有不必要的已使用内存。

票数 1
EN

Stack Overflow用户

发布于 2018-09-25 14:32:37

您尝试过file_get_contents($zipName); unlink($zipName);以便从本地删除文件吗?

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52494643

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档