DOBON.NET DOBON.NETプログラミング掲示板過去ログ

CArchiveクラスで作成されたファイルの読み込み方法

環境/言語:[WindowsXP C#]
分類:[.NET]

お世話になります。
わかる方いらしたらご教授ください。

VC++のCArchiveクラスで作成されたファイル(拡張子は「.dat」)があります。
これをC#で読み込みたいのですが、
どのような方法で読み込めば良いのでしょうか?

テキストで読むと文字化けして意味をなしておりませんし、
バイナリで読み込んで変換しようかと思いましたがうまく行きませんでした。

お恥ずかしながら、VC++はまったくの初心者で、C#も始めたばかりも同然です。
初心者で大変申し訳ないのですが、
やりたいことが可能なのかどうか、
可能だとしたらどのような方法でやれば良いのか、
ご教授いただけないでしょうか。
宜しくお願い致します。
とりあえず、VC++でどのようなルールで書き出したファイルなのかわからなければどうしようもありません。

VC++側のソースで CArchive クラスの >> オペレータおよび Writeメソッドを使っているあたりのソースを見せてください。
■No27694に返信(Blueさんの記事)
> とりあえず、VC++でどのようなルールで書き出したファイルなのかわからなければどうしようもありません。
>
> VC++側のソースで CArchive クラスの >> オペレータおよび Writeメソッドを使っているあたりのソースを見せてください。

Blueさん

素早いレスありがとうございます。
以下、VC++でファイルを作成しているコードです。

CString strFilenm = pApp->m_cstrModulePath + "ファイル名.Dat";

// ファイルを開く
CFile f;
if ( f.Open( strFilenm, CFile::modeCreate | CFile::modeWrite ) == FALSE ) {
return FALSE;
}

// アーカイブオブジェクトを作成する
CArchive ar( &f, CArchive::store ); // Save用

// dataをアーカイブにシリアライズする
for(int i = 0; i < data.GetSize(); i++){
ar << data.GetAt(i).nID; // ID
for(int j = 0; j < 128; j++){
ar << data.GetAt(i).cStr[j];// 文字列
}
ar << data.GetAt(i).bFlg; // フラグ
}
// アーカイブを閉じる
ar.Close();
// ファイルを閉じる
f.Close();

すみませんが宜しくお願いします。
dataという変数はCArrayですか?
構造体かクラスが配列要素になっているようですが、それぞれの型は何でしょうか?

>ar << data.GetAt(i).nID; // ID
>ar << data.GetAt(i).cStr[j];// 文字列
>ar << data.GetAt(i).bFlg; // フラグ
これら。
# CStringだといやだな。

配列数は保存していないのか。めんどくさそうな気もする。
逆に読み込む箇所のソースコードはありますか?
C#もそれにちかいソースになるかと思われます。


ちなみに、VC++で文字コードセットはなんでしょうか?
ソースからは「マルチバイト文字セット」っぽいですけど。
(VC++6.0以前ならほぼ「マルチバイト文字セット」)
Blueさん

レスありがとうございます。

> dataという変数はCArrayですか?
> 構造体かクラスが配列要素になっているようですが、それぞれの型は何でしょうか?
>
> >ar << data.GetAt(i).nID; // ID
> >ar << data.GetAt(i).cStr[j];// 文字列
> >ar << data.GetAt(i).bFlg; // フラグ
> これら。
> # CStringだといやだな。

変数dataはお察しのとおりCArrayです。
それぞれの型は
nID:UNIT
cStr:Char
bFlg:Bool
でした。
取得したいのはIDとフラグなので、
文字列部分は無視しても良いかなと思っています。

> 配列数は保存していないのか。めんどくさそうな気もする。

その時によって配列数は異なるみたいですので、保存されてないものと思われます。

> 逆に読み込む箇所のソースコードはありますか?
> C#もそれにちかいソースになるかと思われます。

ロードしている場所を探しました。
以下、そのコードを抜粋しました。

CString strFilenm = pApp->m_cstrModulePath + "ファイル名.Dat";

CFile f;
_DATA mData;

// ファイルを開く
if ( f.Open( strFilenm, CFile::modeRead ) == FALSE ) {
return FALSE;
}

// アーカイブオブジェクトを作成する
CArchive ar( &f, CArchive::load ); // Load用

// アーカイブから dataにデータをシリアライズする
for(int i = 0; i < data.GetSize(); i++){
memset( &mData, 0, sizeof( _DATA ) );// 構造体ゼロクリア
ar >> mData.nID; // ID
for(int j = 0; j < 128; j++){
ar >> mData.cstr[j]; // 文字列
}
ar >> mData.bFlg; // フラグ
data.SetAt(i, mData);
}
// アーカイブを閉じる
ar.Close();
// ファイルを閉じる
f.Close();


> ちなみに、VC++で文字コードセットはなんでしょうか?
> ソースからは「マルチバイト文字セット」っぽいですけど。
> (VC++6.0以前ならほぼ「マルチバイト文字セット」)
6.0で作成されているようなので、「マルチバイト文字セット」の可能性が高いです。

何度もすみません、宜しくお願いします。
データのサイズは固定なんでしょうか?

>Char
C++にChar型はないですが、char型でしょうか?
>Bool
C++にBool型はないですが、BOOL型でしょうか?


C#ではBinaryReaderクラスを使うと便利でしょう。
http://msdn.microsoft.com/ja-jp/library/system.io.binaryreader_members%28VS.80%29.aspx

C++のUINTはC#でいうとUInt32ですのでReadUInt32メソッドを
C++のchar[128]はSeekしてスキップしてもいいけど、ReadByteで128をつかうとか。
C++のBOOLはintの#defineなので、C#のInt32だからReadInt32メソッドから非0であればtrue、それ以外はfalseとする

という感じでいけそう。
ファイルの最後の判定は必要になるかも。
Blueさん

BinaryReaderクラスで出来ました!
欲しいデータも取れました。
何度もご親切にありがとうございました。

ちなみに
CharとBoolはご指摘どおり表記間違いです。すみません…。

解決済みにしておきますね。
ありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板