アーカイブを使用したファイルの書き込みについて

[戻る]
やす 2009/05/29(金) 11:44:36
アーカイブを使用してファイルのの書き込みを初めて行うのですが、
読み込んだデータをそのまま書き込むとCStringのデータの前に
「00,FF,FE,FF」がついています。
なにかオプションの設定が必要なのでしょうか。

書き込み前のデータ
07,60,04,00,00,00,01,31,00,01,32,09,32,38,36,36,
32,34,30,2B,31,11,30,33,3A,20,50,72,65,73,65,6E,・・・
    ↓ 
書き込み後のデータ
07,60,04,00,00,00,FF,FE,FF,01,31,00,FF,FE,FF,00,
FF,FE,FF,01,32,00,FF,FE,FF,09,32,00,38,00,36,00,
36,00,32,00,34,00,30,00,2B,00,31,00,FF,FE,FF,11,・・・


// シリアライズをオーバーライド
void CMyclass::Serialize( CArchive& ar)
{
    // 派生元をコール
    CObject::Serialize( ar);

    // このクラス固有のデータを保存
    if( ar.IsLoading() == TRUE)
    {
        //読み込み処理
        Load(ar);
    }
    else
    {
        //書き込み処理
        Save(ar);
    }
}
void CMyclass::Save(CArchive &ar)
{
    CString        strBuf;
    long        lRows = m_grid2->get_Rows() - 1;
    long        lCols = m_grid2->get_Cols();
    long        lRow, lCol;
    WORD        wWndID = *m_dwWndID;
    int            nValidCount = *m_lDataNum;

    lRow = m_grid2->get_Row();
    lCol = m_grid2->get_Col();

    ar << wWndID;
    ar << nValidCount;

    for (int i = 0; i < lRows; i++) {
        for (int m = 0; m < lCols; m++) {

            strBuf = m_grid1->get_TextMatrix(i + 1, 4);    
            ar << strBuf;
        }
    }
}

PATIO 2009/05/29(金) 13:48:22
ども、PATIOです。

開発環境に関する説明が全く無いようなので
これで良いかはわかりませんが、
VC++2005で試した限りではそういう現象は起きませんでした。
とは言っても提示されているコードは再現する最小限のコードでは無いので
CStringで作成した変数に"AAA"とか突っ込んで書き出して見ただけですけれど。
CStringをシリアライズすると文字数+文字列と言う形で出力されるみたいですが、
FF,FE,FFなんてデータは出てきたりしていません。

提示するのでしたら再現する最小限のコードで提示しないと
掲示板を見ている人のところで再現できません。

提示されているコードが完全な物で無いのであれば、
省略された所に問題が潜んでいるかもしれません。

aetos 2009/05/29(金) 13:52:07
BOMっぽくも見えますが、微妙に違いますね。

tetrapod 2009/05/29(金) 14:02:29
VC++6 の ARCCORE.CPP を読んだところ Unicode 版の operator<< は
FF FE FF なる "special signature" とコメントに記述あるデータを書いている。
仕様、だと思われる。

aetos 2009/05/29(金) 14:03:34
00,FF,FE,FF がつく、というのはどうも正しくありませんね。

最初の 07,60 が wWndID、次の 04,00,00,00 が nValidCount ですね。
ですから、その次の 01,31 の前についているのは FF,FE,FF ですね。
FF,FE,FF を区切りにしていくと、

07,60,
04,00,00,00,
FF,FE,FF,01,31,00,
FF,FE,FF,00,
FF,FE,FF,01,32,00,
FF,FE,FF,09,32,00,38,00,36,00,36,00,32,00,34,00,30,00,2B,00,31,00,
FF,FE,FF,11,・・・

となると思います。
FF,FE,FF の直後の1バイトは、その後に続く文字数です。
よく見ると、「書き込み前のデータ」として提示されたものと比べ、各文字の後に
「00」が入っていますね。
ということは、Unicode 文字として書かれているみたいですね。
ますます BOM っぽいですが、UTF-16 の BOM は「FE,FF」なので、頭の「FF」は何なん
でしょうね。

ところで。

CArchive で出力したものは、CArchive で読み取ります。
CArchive でちゃんと読み取れるのであれば、何が出力されていようが構わないのではな
いですか?

aetos 2009/05/29(金) 14:06:34
書き忘れ。

従って、CArchive 以外の方法でも読みこむ可能性があるために、余計なデータが出力さ
れては困る場合には、書き出しにも CArchive を使うべきではありません。

やす 2009/05/29(金) 15:10:54
みなさま回答ありがとうございます。
開発環境は、VC2003でWindowsXP、UNICODEオプションで開発しています。

ソースの読み出し方は特になにもやっていないつもりです。(ソースは下の方に記載し
ます)

aetosさんのいわれるように、CArchiveで書いたものは読むことも可能ですので問題ない
のですが、意識していないコードが書き込まれているので気になります。


    bret = f.Open(cReadFile, CFile::modeCreate | CFile::modeWrite);
    if( bret == FALSE){
        // アーカイブ・ファイルをクローズ
        return;
    }

    HinaSerial data;

        data.m_grid1 = &m_grid1;
        data.m_grid2 = &m_grid2;
        data.m_dwWndID = &m_dwWndID;
        data.m_lDataNum = &m_lDataNum;
    
    // アーカイブを作成
    CArchive ar( &f, CArchive::store);
    TRY{
        data.Serialize( ar);
    }
    CATCH_ALL( e){
        ar.Close();
        f.Close();
        return;
    }
    END_CATCH_ALL;

    // アーカイブ・ファイルをクローズ
    ar.Close();
    f.Close();

aetos 2009/05/29(金) 15:30:12
んで、tetrapod さんのコメントで謎は解けたかと思いますが、まだ何かありますか?

> 意識していないコードが書き込まれているので気になります。

CArchive は意識していないデータも書き込むのが仕様です。
バグではありませんので気にしないでください。

やす 2009/05/29(金) 16:38:41
[[解決]]
了解しました。ありがとうございます。

古いスレッドには追加発言できません。