C語言使用fcgi輸出二進制文件

       嘗試使用"Content-Disposition: attachment; filename=test.dat"的http頭的方式來提供文件下載功能,結果發現對於某些文件,下載的文件長度比期望的長,分析後發現,文件中的0x0D('\n')被輸出成0x0A0D("\r\n")。嘗試了各種fcgi中的各種接口,始終無果。 

      最終,在網上各種搜索,終於看到了一篇文章講Python調用"msvcrt.setmode(1, os.O_BINARY) " 可解決類似的問題,於是搜索想到msvcrt.setmode是否爲系統函數,C++也可調用呢,果然,在微軟官網看到C++的例子(附在後面)。

       完整的使用fcgi輸出二進制的數據流的代碼如下:

#include "fcgi_stdio.h"
#include <io.h>
#include <fcntl.h>


void printBinaryFile()
{
    char data[10] = {'A', 0, '\r', 'C', '\n', 'D'};

    //期望文件大小爲6個字節;不調用_setmode的話,下載得到的test.dat文件爲7個字節,因爲把第五個'\n'輸出爲"\r\n"了
    int result = _setmode(_fileno(stdout->stdio_stream), _O_BINARY);
    if (result == -1)
    {
        printf("Content-type: text/html\r\n"
            "\r\n");
        printf("Cannot set mode");
    }
    else
    {
        printf("Content-Disposition: attachment; filename=test.dat\r\n");
        printf("Content-type: application/octet-stream\r\n\r\n");
        fwrite(data, 6, 1, stdout);
    }
}


void main(void)
{
    int count = 0;
    while(FCGI_Accept() >= 0)
    {
        printBinaryFile();
    }
}

 

附:

1、環境說明: windows、vs2010、fcgi2-2.4.2(CGI的C語言庫)。

2、參考鏈接

https://www.7forz.com/2527/

https://docs.microsoft.com/zh-cn/previous-versions/tw4k6df8(v=vs.110)

3、微軟官網上setmode的例子

// crt_setmode.c
// This program uses _setmode to change
// stdin from text mode to binary mode.


#include <stdio.h>
#include <fcntl.h>
#include <io.h>

int main( void )
{
   int result;

   // Set "stdin" to have binary mode:
   result = _setmode( _fileno( stdin ), _O_BINARY );
   if( result == -1 )
      perror( "Cannot set mode" );
   else
      printf( "'stdin' successfully changed to binary mode\n" );
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章