- ベストアンサー
バイナリ読み込み時のデータ受け渡しについて
質問させていただきます。 XMLファイルを圧縮後にバイナリ読み込みし、long*に設定してそれを4バイトのlong配列に格納したいと考えています。 ファイルを読み込む際にはデータ数が解らないので、ループを回したいと思っています。 以下に一部記載します。 これでpBinaryには正常にバイナリデータが入るのでしょうか? わかる方がいれば教えてください。 ****************************************** FILE *pFile = NULL; pFile = fopen("XMLFile.xml", "rb"); int iRet = 0; int iSize = 0; bool bRet = false; long *pBinary = new long; while(bRet != true) { /* 4バイトずつ読み込みpBinaryに設定する */ fread(pBinary, sizeof(4), 1, pFile); if(iRet != 1) { bRet = true; } else { iSize++; } }
- みんなの回答 (11)
- 専門家の回答
質問者が選んだベストアンサー
> 最終的にはバイナリ読み込みしたファイルデータをlong配列に格納できれば良いのです。 ならば std::vector<char> bytebuffer; に読み込んで。 long* buffer = reinterpret_cast<long*>(&bytebuffer[0]); でいいんじゃないすか?
その他の回答 (10)
- charmer29-2
- ベストアンサー率25% (41/159)
なかなか間違いだらけの楽しいコードですがそれはさておき。 圧縮済みのファイルを読み込んでなにをしたいのでしょう。 やりたいことによってはlongの配列にしたいのかもしれませんが、 例えば単にコピーするなどの目的ならNo.10さんの回答のようにcharの配列に入れてしまえばいいでしょう。 どんな処理をしたいのかが判れば、もっと適当な回答も出てくると思いますよ。
- tatsu99
- ベストアンサー率52% (391/751)
>最終的にはバイナリ読み込みしたファイルデータをlong配列に格納できれば良いので す。 どうして、long型の配列にこだわるのかが、判りません。 最後のデータが、4バイトちょうどに収まらない場合は、どのようにされたいのでしょうか。 単純に考えると、long型に1バイトずつ左詰め(もしくは右詰め)にするしか、方法はないと思いますが、その場合でも、そのように格納したことを別途覚えておく必要が発生します。 >1バイト毎にlongに読み込んで、longの配列に格納すれば何バイトでも正常に格納可能なんですね。 可能です。1バイトずつ読み込んだ場合は、4回読み込んで、1つのlong型に格納ということになります。(多少ビットの操作等が必要になります。もしくは1つのlong型変数を1バイトの配列4つに見立て方法もありますが)
- tatsu99
- ベストアンサー率52% (391/751)
通常、バイナリーデータなどは、1バイト毎に処理します。 1.4バイト単位で、読み込むのは、処理速度を上げたい為なのでしょうか? 2.配列に格納した後、その格納したデータをどうされたいのでしょうか。つまり、本当になさりたいことは、何なのでしょうか? 上記のことが、判ると、もっと良い回答が得られるかもしれません。 一般論としては、以下のようにします。 1.読み込みバッファー(読み込む領域)を大きくとる。 (約64Kバイトぐらい。この64の根拠は、経験値) 2.64Kバイト毎に、一気に読む。 その時に、何バイト読めたが判るので、そのサイズ分を処理する。 (通常は、64Kバイトの読み込み成功がN回続き、最後の1回がMバイトになります(Mは64Kバイト以内))
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> 末尾はどのように対処するのが得策でしょうか? 知りません。long配列に格納しようとは思っていませんから。
補足
末尾問題も無事に解決しました。 何度もアドバイス頂きましてアリガトウございます! 今回の質問でやり取りする中できちんと理解することができました。 それではレベルの高いプログラムが書けるように頑張りたいと思います!。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
末尾の問題はなんとかするとして: std::vector<long> buffer; long tmp; while ( ファイルからtmpに4バイト読み込む ) { buffer.push_back(tmp); } long* pBinary = &buffer[0]; // 読み込んだlong列の先頭 long size = buffer.size(); // long列の長さ
補足
fread(tmp, 4, 1, pFile);でファイルから読み込んでlong型のvector配列に格納するんですね。 末尾はどのように対処するのが得策でしょうか? 全く同じバイナリデータで無いとファイルの復元は出来ないですよね?
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
>>pBianryに確保された領域を一度も大きくしていないから。 > とはどう解決すればいいのでしょうか? > アドバイスをお願い致します。 そもそも、読み込み対象であるファイルのサイズが4の倍数でなかったら、末尾が狂いませんか? 僕なら「longの配列に…」を改めます。
補足
確かにそうですね・・ 例えば最終的な設定対象がlongの配列であるとすれば ファイルの読み込みはchar*にしてlong*に変換して設定対象に格納するといった流れでしょうか? どんな処理ならうまく渡せるかイメージできないんです・・
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> fread(pBinary, sizeof(4), 1, pFile); とんでもない勘違い。sizeof(4)ってなんですか?
補足
fread関数が下記のようなので、4バイトという意味で書きました。 sizeofは必要ありませんでしたね・・ size_t fread(void *buf, size_t size, size_t n, FILE *fp); size_t size : 読み込みデータのバイト長さ またアドバイス等がありましたら回答頂けると助かりますのでよろしくお願い致します。
#2の補足です。 質問の内容が、ファイル内の全データをpBinaryに格納するということでしたら、epistemeさんのおっしゃるとおりだと思います。 当方、pBinaryにはファイルから4バイトだけデータを読み込んで、値は別のバッファに移すなどの処理を行うもんだと思って #2 に回答しました。 以上です。
補足
回答して頂きましてアリガトウございます。 ファイル内のデータをlong*に格納するとすればどんな処理の流れになるのでしょうか? 教えて頂けると助かります。
正常に動作すると思います。 ほかに、fread()で読み込む処理をループして、fread()の戻り値が0になったら抜ける形でもいいと思います。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> これでpBinaryには正常にバイナリデータが入るのでしょうか? 入りません。 pBianryに確保された領域を一度も大きくしていないから。
補足
回答してくださいましてありがとうございます。 >pBianryに確保された領域を一度も大きくしていないから。 とはどう解決すればいいのでしょうか? アドバイスをお願い致します。
補足
1バイト毎にlongに読み込んで、longの配列に格納すれば何バイトでも正常に格納可能なんですね。 最終的にはバイナリ読み込みしたファイルデータをlong配列に格納できれば良いのです。