1

特別にフォーマットされた情報をバイナリファイルに書き込む方法をようやく理解しましたが、今の私の問題は、それを読み戻し、元の状態に戻すことです。

データを書き込むための私の関数は次のとおりです。

void save_disk(disk aDisk)
{
    ofstream myfile("disk01", ios::out | ios::binary);
    int32_t entries;
    entries = (int32_t) aDisk.current_file.size();
    char buffer[10];
    sprintf(buffer, "%d",entries);

    myfile.write(buffer, sizeof(int32_t));

    std::for_each(aDisk.current_file.begin(), aDisk.current_file.end(), [&] (const file_node& aFile)
    {
        myfile.write(aFile.name, MAX_FILE_NAME);
        myfile.write(aFile.data, BLOCK_SIZE - MAX_FILE_NAME);
    });

}

そして、それが最初に作成された私の構造と、それをロードし直したいものは、次のように構成されています。

struct file_node
{
    char  name[MAX_FILE_NAME];
    char  data[BLOCK_SIZE - MAX_FILE_NAME];

    file_node(){};
};

struct disk
{
    vector<file_node> current_file;
};

同じように配置されるように読み戻す方法はよくわかりませんが、とにかく哀れな試みがあります(保存のために行ったことを逆にしようとしました):

void load_disk(disk aDisk)
{
    ifstream myFile("disk01", ios::in | ios::binary);
    char buffer[10];

    myFile.read(buffer, sizeof(int32_t));

    std::for_each(aDisk.current_file.begin(), aDisk.current_file.end(), [&] (file_node& aFile)
    {
        myFile.read(aFile.name, MAX_FILE_NAME);
        myFile.read(aFile.data, BLOCK_SIZE - MAX_FILE_NAME);
    });

}

^^これは絶対に間違っています。^^

私はifstreamの基本的な操作を理解していますが、実際にそれを使用する方法を知っているのは、テキストのファイルで読み取られます。それよりも複雑なことは、私が少し迷っています。

これをどのように読むことができるかについての提案はありますか?

4

1 に答える 1

1

あなたはとても近くにいます。長さをバイナリとして読み書きする必要があります

あなたの長さの書き込みのこの部分は間違っています:

char buffer[10];
sprintf(buffer, "%d",entries);
myfile.write(buffer, sizeof(int32_t));

長さが何であれ、最初の 4 バイトのみを書き込みますが、長さはsprintf()呼び出しからの文字データです。entriesこれを(整数)のバイナリ値として記述する必要があります。

// writing your entry count.
uint32_t entries = (uint32_t)aDisk.current_file.size();
entries = htonl(entries);
myfile.write((char*)&entries, sizeof(entries));

次に、読み取り時に:

// reading the entry count
uint32_t entries = 0;
myFile.read((char*)&entries, sizeof(entries));
entries = ntohl(entries);

// Use this to resize your vector; for_each has places to stuff data now.
aDisk.current_file.resize(entries);
std::for_each(aDisk.current_file.begin(), aDisk.current_file.end(), [&] (file_node& aFile)
{
    myFile.read(aFile.name, MAX_FILE_NAME);
    myFile.read(aFile.data, BLOCK_SIZE - MAX_FILE_NAME);
});

またはそのようなもの。

注 1: これはエラー チェックを行わず、異なるホスト マシン (ファイルを書き込むビッグ エンディアン マシン、ファイルを読み取るリトル エンディアン マシン) でエンディアンが異なる可能性がある場合の移植性を考慮しません。それはおそらくあなたのニーズには問題ありませんが、少なくともそれを認識しておく必要があります.

注 2: 入力ディスク パラメータをload_disk()参照渡しで渡します。

void load_disk(disk& aDisk)

EDITfile_node工事中の清掃内容

struct file_node
{
    char  name[MAX_FILE_NAME];
    char  data[BLOCK_SIZE - MAX_FILE_NAME];

    file_node()
    { 
        memset(name, 0, sizeof(name));
        memset(data, 0, sizeof(data));
    }
};

準拠した C++11 コンパイラを使用している場合:

struct file_node
{
    char  name[MAX_FILE_NAME];
    char  data[BLOCK_SIZE - MAX_FILE_NAME];

    file_node() : name(), data() {}
};
于 2012-11-25T09:09:00.293 に答える