2011-08-08 10 views
0

イメージファイルをscket経由で送信するためにバッファにロードしようとしています。問題は、プログラムが有効なサイズのバッファを作成するが、ファイル全体をバッファにコピーしないということです。私のコードは、ファイルをチェックし、私は倍増(出力から続く画像ファイルをバッファ(gif、jpegなど)に保存しています。

//imgload.cpp 
#include <iostream> 
#include <stdlib.h> 
#include <stdio.h> 
using namespace std; 

int main(int argc,char *argv){ 

    FILE *f = NULL; 
    char filename[80]; 
    char *buffer = NULL; 
    long file_bytes = 0; 
    char c = '\0'; 
    int i = 0; 

    printf("-Enter a file to open:"); 
    gets(filename); 

    f = fopen(filename,"rb"); 
    if (f == NULL){ 
     printf("\nError opening file.\n"); 
    }else{ 
     fseek(f,0,SEEK_END); 
     file_bytes = ftell(f); 
     fseek(f,0,SEEK_SET); 

     buffer = new char[file_bytes+10]; 

    } 

    if (buffer != NULL){ 
     printf("-%d + 10 bytes allocated\n",file_bytes); 
    }else{ 
     printf("-Could not allocate memory\n"); 
     // Call exit?. 
    } 

    while (c != EOF){ 
     c = fgetc(f); 
     buffer[i] = c; 
     i++; 
    } 

    c = '\0';     
    buffer[i-1] = '\0';  // helps remove randome characters in buffer when copying is finished.. 
    i = 0;  

    printf("buffer size is now: %d\n",strlen(buffer)); 



    //release buffer to os and cleanup.... 




    return 0; 
} 

>出力

c:\Users\Desktop>imgload 
-Enter a file to open:img.gif 
-3491 + 10 bytes allocated 
buffer size is now: 9 


c:\Users\Desktop>imgload 
-Enter a file to open:img2.gif 
-1261 + 10 bytes allocated 
buffer size is now: 7 

として、私はそれがそれぞれの画像3491と1261バイトの正しいサイズを割り当てるだことを見ることができますされてサイズウィンドウと割り当てられているサイズは正しいですが)、おそらくコピー後のバッファサイズは9と7バイトです。データ全体をコピーしないのはなぜですか?

+0

これもすべて単純なWebsrverを実装するために行われていますが、私はこの方法で画像を送信できないようです。すべてのtext/htmlファイルは、このメソッドを使用して正常に送信されます。 – silent

+0

HTTPプロトコルが送信するデータのタイプがわかりません。プレーンテキストの場合、イメージをMIMEコーディングでエンコードする必要があります。テキストシンボルでバイナリデータを変換するので、ファイルはE-MAILなどで送信できます。バイナリデータとして画像を送る場合は、 'Content-Type'ヘッダを変更することをお勧めします。それらについてもっと学んでください。 –

+0

while()ループはボルケージされています。 fgetc()は、charではなくintを返します。あなたがそれを使用する方法では、EOFを正しく検出することはできません。 Ditch strlen()、それは文字列ではありません。 –

答えて

6

あなたは間違っています。画像はバイナリデータでも文字列データでもありません。したがって、2つのエラーがあります:

1)ファイルの最後をEOFでチェックすることはできません。 EOFは0xFFとしばしば定義され、バイナリファイルの有効なバイトです。したがって、ファイルの末尾を確認するにはfeof()関数を使用してください。または、可能な限りファイル内の現在の位置を確認することもできます(これまではftell()となっています)。

2)ファイルがバイナリなので、中間に\0が含まれている可能性があります。したがって、そのようなデータを処理するために文字列関数を使用することはできません。

また、C++言語を使用しています。ファイル作業に古典的なC構文を使用する理由を教えてください。ファイルストリーム、コンテナ、イテレータなどのC++機能を使用すると、プログラムが簡単になると思います。

P.S.そして、私はあなたのプログラムは本当に大きなファイルに問題があると言いたいと思います。多分あなたが彼らと一緒に仕事をしようとするだろうことを誰が知っています。 「はい」の場合は、(long long int)に対応するftell/fseekの機能を書き換えます。また、配列カウンターを修正する必要があります。もう1つの良いアイデアはブロック単位でファイルを読むことです。バイト単位での読み取りは劇的に遅くなります。

+0

私はバイナリモードで開きますか? (「rb」)。 – silent

+0

意味がありません。 –

+0

あなたが助けてくれてありがとう、ありがとう。できます。 – silent

4

このすべてが不要で、実際には意味がありません:

c = '\0';     
buffer[i-1] = '\0'; 
i = 0; 

printf("buffer size is now: %d\n",strlen(buffer)); 

バイナリデータためstrlenを使用しないでください。 strlenは、最初のNUL\0)バイトで停止します。バイナリファイルにはこのようなバイトが多数含まれる可能性があるため、NULは使用できません。

-3491 + 10 bytes allocated /* There are 3491 bytes in the file. */ 
buffer size is now: 9 /* The first byte with the value 0. */ 

結論として、その部分をドロップします。あなたはすでにファイルのサイズを持っています。

+0

イメージバイナリデータの内容をバッファにコピーするには? – silent

+0

@ sil3ntあなたはすでにバッファー内のデータを 'fgetc'ループ経由でコピーしています。 – cnicutar

+0

hmm ..私はまだブラウザで画像を受け取っていません。 – silent

1

テキストファイルのようなバイナリファイルを読み込んでいます。これはバイナリファイルのどこにでもある可能性があるため、EOFをチェックすることはできません。

関連する問題