はじめまして、トムと申します。
fread関数に関して質問があります。
現在ソケット通信でファイルをやりとりしています。
ソケットで送られて来たファイルをfread関数を用いて
データの頭から読み込み、随時fwrite関数で
別ファイルに書き込みをしているのですが、
処理後のファイルを見るとファイル内にゴミが
入ってしまいます。
ソケット通信を行わない場合は、ゴミは入りません。
この件に関して何かご存知の方がいらっしゃいましたら
教えて頂けないでしょうか。
よろしくお願い致します。
<<開発環境>>
Windows2000
Windows2000Server
VC++6.0
ソースがないので想像ですが、
fread()に指定したサイズと実際に読み込まれたサイズが
違う場合を想定していますか?
いまいち状況が把握できないのですが、私が昔々やったミスだと・・・
1.バッファの空読みしてる
2.取得データサイズ以上を参照してる
etc...
そのごみの状態がわからないのでなんともいえませんが、
データリードの前にバッファを0クリアなりして、ごみがどう出るかとか見てみる。
あ、ソケット通信で取得したファイルか・・・
んじゃ、見るところはそのファイルの取得場所ですね
# この文面だと・・・fread以降と通信と別処理?
# それとも、通信の最中に書き出し?
書いた直後にちょっと気になり・・・追記です。
送信側で、ごみも送ってる可能性もありますねぇ~
# サーバークライアント構成だったらですが・・・
ご返事ありがとうございます。
>dairygoodsさんへ
fread()に指定したサイズと実際に読み込まれたサイズは、
毎回違うのですが、そういった場合を想定しなくてはいけないの
でしょうか?
バッファサイズよりも取得したデータは小さいです
>あいるさんへ
データリードの前に0クリアをしてみましたが、ゴミが多少消えただけで
残ってしまいました・・・。
少し訂正なのでゴミというより取得したデータが改行されずにめちゃくちゃに
なってしまいます。
ちなみにfread()は通信の最中に書き出しています。
> fread()に指定したサイズと実際に読み込まれたサイズは、
> 毎回違うのですが、そういった場合を想定しなくてはいけないの
> でしょうか?
> バッファサイズよりも取得したデータは小さいです
fread は、実際に読み出されたバイト数を返します。
この値以上のバイト数を書き込むとゴミがでるのはわかりますよね?
(ゴミが出るというより、予期しないデータが書き込まれる・・・同じかw)
> データリードの前に0クリアをしてみましたが、ゴミが多少消えただけで
> 残ってしまいました・・・。
> 少し訂正なのでゴミというより取得したデータが改行されずにめちゃくちゃに
> なってしまいます。
0クリアの意味は、想定しているデータが正しいかどうかを判断するための手段にしかすぎませ
ん。
(デバッグできたら0クリアの必要ないですよ~)
freadの返り値分以外のバイトは0になってるはずですから、単に読み込みバイト数がバッファ
のサイズより小さいときに、バッファサイズ分書き出すと0がたくさん入りますよね?
コーディングのミスでそういうことが起きてないかとかをチェックする為だと思ってください。
んで、本題・・・
えっと・・・改行がなくなるってことは・・・おそらく・・・
ストリームがテキストモードで開いてるのだと思います。
fread はストリームがテキストモードで開かれていると、CR-LFをLFに置換して読み込むため、
そういうことが起きます。(fwriteではその逆)
データをそのままコピーするならば、読み込みも書き込みもバイナリーモードでオープンする方
がミスは出ないかな~?
# 通信中の読み書きってことですが、同期とか大丈夫です?
# その辺りで、データが書き込まれてないのに読み書きすると意図しないデータだったり・・・
# 順番にひとつずつデバッグすることをお勧めします。
一部訂正・・・(恥
> fread はストリームがテキストモードで開かれていると、CR-LFをLFに置換して読み込
> むため、そういうことが起きます。(fwriteではその逆)
fwrite はCRをCR-LFに置換して書き出しますでした・・・
あいるさんへ
ご返答ありがとうございます。
freadについてなのですが、テキストモードではなくバイナリモードで
読み込み書きしています。rb, wb
読み書きの問題じゃないのでしょうか。
デバッグしながら追っていくとうまくファイルに書き込めているのですが。。
もし仮にソケット通信で失敗している場合は、どのように追っていったら
良いのでしょうか?ソケットのデータが本当に正しい値なのかどうか
判断できません。。
すみませんが、よろしくお願い致します。
簡単なバイナリデータなりを作って、実験するとよいのでは?
たとえば・・・
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e
10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e
…
とか、判断しやすいデータを使えばいいと思いますよ
# データはある程度の大きさ必要になるとおもいますが・・・
後は同じように受信のところで、バッファクリアして読み込んでデータみて・・・
で、想定してるデータかどうかチェックすれば、通信がおかしいのかその後の処理がおかしいの
か切り分けできるかと・・・
えーと、freadで指定しているサイズと取得しているサイズが違っている件は
どうなったんでしょうか?
freadに指定しているのは読み込める最大サイズですから、必ず最大サイズ読み込める
とは限りませんよね。
ローカルのファイルを単純に読むだけならファイルの終端に達しない限りは
指定したサイズ分読み込めると思いますが、通信処理の場合は読み込みに行った
タイミングによって通信バッファ上のデータサイズは異なりますから
書き込んだり、データを処理したりする時のデータサイズは読み込めたサイズを対象に
行う必要があります。
これをfreadに指定した読込の最大サイズを使って処理しているとごみが出ることが
あると思います。
読込側のタイミングが早ければ、全く読み込めないような状況だってありえると
思いますしね。
ソケットから読み込んだ生の情報をそのままログに吐き出すとか、
TRACEでIDEのウインドウの出させるとかすれば、少なくとも通信時に
化けているかは確認できませんか?
ブレイクポイントで止めてしまうと実際に動いているタイミングと違うタイミングで
動いてしまうと思うので極力ブレイクポイントを使わないでテストしてみた方が良いと
思います。
あと、送り側のデータ内容がわかっていれば、受信データが正しいかどうか解らないと
いうような事態はありえないと思うのですが、その辺はどうなっているんでしょう?
あと、ソケット通信を使わないでやり取りすると言う書き込みがありますが、
それはどういう処理を指して言っていますか?