2016-10-14 4 views
0

私は単純なソケットプログラムを作成して、テキストファイルや画像ファイルをポートに接続された別のソケットに送ります。しかし、ファイルのサイズをクライアントソケットに送信して、受信するバイト数を知りたいとします。ファイルのサイズを表示する[C]

また、ファイル自体の代わりに特定のバイト数を送信できる場所を実装したいと考えています。たとえば、送信したいファイルが14,003バイトで、400バイトを送信するように感じた場合、400バイトしか送信されません。

私はこのような何か実装しています:

#include <stdio.h> 

int main(int argc, char* argv[]) { 
    FILE *fp; 
    char* file = "text.txt"; 
    int offset = 40; 
    int sendSize = 5; 
    int fileSize = 0; 

    if ((fp = fopen(file, "r")) == NULL) { 
     printf("Error: Cannot open the file!\n"); 
     return 1; 
    } else { 
     /* Seek from offset into the file */ 
     //fseek(fp, 0L, SEEK_END); 
     fseek(fp, offset, sendSize + offset); // seek to sendSize 
     fileSize = ftell(fp); // get current file pointer 
     //fseek(fp, 0, SEEK_SET); // seek back to beginning of file 
    } 

    printf("The size is: %d", fileSize); 
} 

offsetはかなりのファイルに40のバイトを移動して、他のプログラムにどんなsendSizeバイトを介して送信しようとしています。

5の代わりに0という出力が得られます。これの背後にある理由?

+0

'#include 'で 'sendfile'(例えば' man sendfile'を見てください)を見てください。オフセット/転送で何をしているのですか? –

+0

あなたの 'whence'は正しくありません。 'fseek(fp、sendSize、SEEK_SET);' –

+0

@ DavidC.Rankinいいですね。しかし、もし私が 'sendfile'の代わりにこのメソッドを使いたいのであれば、できますか?私はすべてのサイズを設定する面で見えると思う。 –

答えて

-1

私はあなたのシークが原因第三パラメータに動作しないと思う: 彼は「起源」の定数としてオフセット数SENDSIZE +を使用しようとして
(fp, offset, SEEK_SET);

を追求しようとすると、それは以下の3つの定数値(0,1,2)と比較され、何も比較しないので、常に0を返すように見えます。

http://www.cplusplus.com/reference/cstdio/fseek/

パラメータ

ストリーム、オフセット、原点

位置オフセットの基準として使用されます。ファイル



一定の基準位置ファイルの
SEEK_SET先頭
ファイルポインタの SEEK_CUR現在位置
SEEK_END終了:それは、この関数の引数として使用する独占的に定義された次の定数のいずれかで指定されています
1

これを試すことができます。

#include <stdio.h> 

int main(int argc, char* argv[]) { 
    FILE *fp; 
    char* file = "text.txt"; 
    int offset = 40; 
    int sendSize = 5; 
    int fileSize = 0; 

    if ((fp = fopen(file, "r")) == NULL) { 
     printf("Error: Cannot open the file!\n"); 
     return 1; 
    } else { 
     fseek(fp, 0L, SEEK_END); 
     fileSize = ftell(fp); 
    } 

    printf("The size is: %d", fileSize); 
} 
+0

正しい。しかし、それはクライアントソケットに情報を送信することでやりたいことではありません。私は、ファイルに 'offset'バイトを入れ、' offset'から 'sendSize'バイトを送るだけです。 –

+0

シーカーを元に戻すことを忘れないでください! –

+0

'0'が動作するときに' 0L'を使用し、 'ftell()'の戻り値の型にマッチするのではなく、 'int fileSize'を使用しています。 – chux

1

最後にfseek()を呼び出すと、ftell()メソッドはファイルのサイズを取得するのに合理的に移植可能ですが、正しいとは限りません。改行/改行の変換を透過的に処理しないため、標準では実際にftell()からの戻り値が同じ位置を探す以外の目的には役に立たないことを実際に保証しません。

唯一の移植可能な方法は、データがなくなるまでファイルを読み取り、バイト数を保持することです。または、(非ANSI)Unix標準関数を使用してファイルをstat()します。

1

ファイルをテキストモードでWindows can open a file in text mode even without the "t" optionとして開いている可能性があります。

ftell()を使用して、テキストモードで開いたファイルのサイズを取得することはできません。 Per 7.21.9。4 C標準のftell機能:テキストストリームについて

、そのファイル位置インジケータは、その位置へのストリームのファイル 位置インジケータを返すfseek機能が利用可能な不特定情報が含まftellコールの時刻 ; このような2つの戻り値の差は、 の値の意味のある尺度であるとは限りません。 文字の数は、必ずとなります。

ファイルの「サイズ」が返されても、「テキスト」に変換すると実際の読み込みバイト数が変わることがあります。

fseek()を使用すると、バイナリファイルの末尾を見つけるために移植性がなく、標準に準拠していません。 7.21.9.2あたり fseek機能

バイナリストリームはSEEK_ENDwhencefseekコールをサポート有意義必要はありません。

関連する問題