最后更新于 .

最近在做公司的一个内部管理系统,因为自己php不熟,公司又没有asp.net的环境,所以自己最后居然用js+CGI的模式,运行速度倒是飞快了,编码却麻烦的要死……罪过啊,罪过,又不是外网……
废话不多说了,有一个问题就是要在调用我的CGI的时候,返回一个文件下载对话框。
好吧,在网上搜了一下,实际上只是http头里面有这样一段就可以了:

Content-Disposition:   attachment;   filename= %s\r\n\r\n

找到了php版如下:

$old_name = "E:\a.doc";
$file_name = "新文件名.doc";
if (!file_exists($old_name)) { //检查文件是否存在
    echo "文件找不到";
    exit;
} else {
    $file = fopen($old_name, "r"); //   打开文件
    //   输入文件标签
    Header("Content-type:   application/octet-stream");
    Header("Accept-Ranges:   bytes");
    Header("Accept-Length:   ".filesize($old_name));
    Header("Content-Disposition:   attachment;   filename=".$file_name);
    //   输出文件内容
    echo fread($file, filesize($old_name));
    fclose($file);
    exit;
}

C#版如下:

public static void ToDownload(string serverfilpath,string filename)
{
    FileStream fileStream = new FileStream(serverfilpath, FileMode.Open);
    long fileSize = fileStream.Length;
    HttpContext.Current.Response.ContentType = "application/octet-stream";
    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"" +UTF_FileName(filename) + "\";");
    ////attachment — 作为附件下载
    ////inline — 在线打开
    HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
    byte[] fileBuffer = new byte[fileSize];
    fileStream.Read(fileBuffer, 0, (int)fileSize);
    HttpContext.Current.Response.BinaryWrite(fileBuffer);
    fileStream.Close();
    HttpContext.Current.Response.End();
}
public static void ToOpen(string serverfilpath, string filename)
{
    FileStream fileStream = new FileStream(serverfilpath, FileMode.Open);
    long fileSize = fileStream.Length;
    HttpContext.Current.Response.ContentType = "application/octet-stream";
    HttpContext.Current.Response.AddHeader("Content-Disposition", "inline; filename=\"" + UTF_FileName(filename)+ "\";");
    HttpContext.Current.Response.AddHeader("Content-Length", fileSize.ToString());
    byte[] fileBuffer = new byte[fileSize];
    fileStream.Read(fileBuffer, 0, (int)fileSize);
    HttpContext.Current.Response.BinaryWrite(fileBuffer);
    fileStream.Close();
    HttpContext.Current.Response.End();
}
private static string UTF_FileName(string filename)
{
    return HttpUtility.UrlEncode(filename, System.Text.Encoding.UTF8);
}

所以其实最后的C++版也就比较明显了(我没有读本地文件,因为内容直接在一个string的buff里):

printf("Content-type:   application/octet-stream\r\n");
printf("Content-Length: %u\r\n",ccpp.filecontent.size());
printf("Content-Disposition:   attachment;   filename= %s\r\n\r\n",filename.c_str());
const char *ptr = ccpp.filecontent.c_str();
for(unsigned int i =0 ;i < ccpp.filecontent.size();++i)
{
    putchar(*(ptr+i));
}

先解释一下,由于webserver会将标准输出重定向,所以用printf实际就是返回到了浏览器端,至于用putchar是因为二进制的原因。
在这里还碰到了一个诡异的问题,即用

write(1,ptr,ccpp.filename.size());

会直接500 error,不知道为什么……

Pingbacks

Pingbacks已打开。

Trackbacks

引用地址

评论

  1. gf

    gf on #

    赞一个!!

    Reply

  2. Biafeffog

    Biafeffog on #

    Nice site <a href="http://google.com" rel="nofollow">....)</a>

    Reply

  3. Biafeffog

    Biafeffog on #

    <a href="http://lqzjbbxi.com" rel="nofollow"> :)</a>

    Reply

发表评论