如何强制大文件下载,而无需使用太多的内存? [英] How to force download of big files without using too much memory?

查看:266
本文介绍了如何强制大文件下载,而无需使用太多的内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想大的zip文件服务给用户。当有2个并发连接,服务器运行的内存(RAM)。我增加了内存容量300MB,从到4GB(Dreamhost的VPS),然后它工作得很好。

I'm trying to serve large zip files to users. When there are 2 concurrent connections, the server runs out of memory (RAM). I increased the amount of memory from 300MB to 4GB (Dreamhost VPS) and then it worked fine.

我需要让很多超过2个并发连接多。实际4GB将允许像20个并发连接(坏)。

I need to allow a lot more than 2 concurrent connections. The actual 4GB would allow something like 20 concurrent connections (too bad).

那么,目前的code我使用,需要记忆的双重那么实际文件的大小。这太糟糕了。我想是这样流文件的用户。因此,我将拨出不超过该块被提供给用户。

Well, the current code I'm using, needs the double of memory then the actual file size. That's too bad. I want something like "streaming" the file to user. So I would allocate not more than the chunk being served to users.

以下code是我使用在codeIgniter一(PHP框架):

The following code is the one I'm using in CodeIgniter (PHP framework):

ini_set('memory_limit', '300M'); // it was the maximum amount of memory from my server
set_time_limit(0); // to avoid the connection being terminated by the server when serving bad connection downloads
force_download("download.zip", file_get_contents("../downloads/big_file_80M.zip"));exit;

该force_download功能如下(codeingiter默认辅助函数):

The force_download function is as follows (Codeingiter default helper function):

function force_download($filename = '', $data = '')
{
    if ($filename == '' OR $data == '')
    {
        return FALSE;
    }

    // Try to determine if the filename includes a file extension.
    // We need it in order to set the MIME type
    if (FALSE === strpos($filename, '.'))
    {
        return FALSE;
    }

    // Grab the file extension
    $x = explode('.', $filename);
    $extension = end($x);

    // Load the mime types
    @include(APPPATH.'config/mimes'.EXT);

    // Set a default mime if we can't find it
    if ( ! isset($mimes[$extension]))
    {
        $mime = 'application/octet-stream';
    }
    else
    {
        $mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
    }

    // Generate the server headers
    if (strpos($_SERVER['HTTP_USER_AGENT'], "MSIE") !== FALSE)
    {
        header('Content-Type: "'.$mime.'"');
        header('Content-Disposition: attachment; filename="'.$filename.'"');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header("Content-Transfer-Encoding: binary");
        header('Pragma: public');
        header("Content-Length: ".strlen($data));
    }
    else
    {
        header('Content-Type: "'.$mime.'"');
        header('Content-Disposition: attachment; filename="'.$filename.'"');
        header("Content-Transfer-Encoding: binary");
        header('Expires: 0');
        header('Pragma: no-cache');
        header("Content-Length: ".strlen($data));
    }

    exit($data);
}

我尝试了一些基于块codeS,我在谷歌发现,但文件始终交付损坏。可能是因为不良code。

I tried some chunk based codes that I found in Google, but the file always was delivered corrupted. Probably because of bad code.

谁能帮助我?

推荐答案

有一些想法在上的此线程。我不知道,如果ReadFile的()方法将节省内存,但它听起来很有希望。

There are some ideas over in this thread. I don't know if the readfile() method will save memory, but it sounds promising.

这篇关于如何强制大文件下载,而无需使用太多的内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆