インメモリデータの読み取りと書き込み

samuelbrody1249

次の例では、メモリ内で32バイトを占有する構造体を取得し、それをファイルに書き込んで読み戻します。つまり、データをバイナリ形式にシリアル化します。

#include <stdio.h>

typedef struct _Person {
    char   name[20];
    int    age;
    double weight;
} Person;

int main(void)
{

    Person tom = (Person) {.name="Tom", .age=20, .weight=125.0};

    // write the struct to a binary file
    FILE *fout = fopen("person.b", "wb");
    fwrite(&tom, sizeof tom, 1, fout);
    fclose(fout);

    // read the binary data and set the person to that
    Person unknown;
    FILE *fin = fopen("person.b", "rb");
    fread(&unknown, sizeof unknown, 1, fin);
    fclose(fin);

    // confirm all looks ok
    printf("{name=%s, age=%d, weight=%f}", unknown.name, unknown.age, unknown.weight);

}

ただし、これらはすべてスタック上の値であり、ポインター/間接参照は含まれないことに注意してください。たとえば、複数のポインタが含まれる可能性がある場合、複数の変数が同じメモリ位置を指す場合など、データをファイルにシリアル化するにはどうすればよいでしょうか。これは事実上、プロトコルバッファが行うことですか。

ヨシュア

さて、バイナリファイルが必要です。私はずっと前にこのようにそれをしていました。大丈夫だよ。別のプラットフォームやビットネスに移動すると、壊れてしまいます。始めるのに良い場所なので、私は古い方法を教えています。プラットフォームやビットネスを変更するときに機能し続けるため、新しい方法が現在人気があります。

ファイルにレコードを書き込むときは、次のような構造体を使用します。

typedef struct _Person {
    char   name[20];
    int    age;
    double weight;
} Person;

typedef struct _Thing {
    char name[20];
};

typedef struct _Owner {
    int personId;
    int thingId;
} Owner;

Owner構造にIdメンバーがどのように含まれているかを確認してくださいこれらは、他の構造の配列への単なるインデックスです。

これらは次々にファイルに書き出すことができ、通常、各種類のレコードの数を示す直接書き込まれた単一の整数が接頭辞として付けられます。リーダーは、mallocそれらを保持するのに十分な大きさの構造体の配列を割り当てるだけです。メモリにアイテムを追加するときに、配列のサイズをrealloc。で変更します削除(たとえば、名前の最初の文字を0に設定することによって)および後でレコードを再利用するためにマークを付けることもできます(そしてそうすべきです)。

ライターは次のようになります。

void writeall(FILE *h, Person *allPeople, int nPeople, Thing *allThings, int nThings, Owner *allOwners, int nOwners)
{
    // Error checking omitted for brevity
    fwrite(&nPeople, sizeof(nPeople), 1, h);
    fwrite(allPeople, sizeof(*allPeople), nPeople, h);
    fwrite(&nThings, sizeof(nThings), 1, h);
    fwrite(allThings, sizeof(*allThings), nThings, h);
    fwrite(&nOwners, sizeof(nOwners), 1, h);
    fwrite(allOwners, sizeof(*allOwners), nOwners, h);
}

リーダーは次のようになります。

int writeall(FILE *h, Person **allPeople, int *nPeople, int *aPeople, Thing **allThings, int *nThings, int *aThings, Owner **allOwners, int *nOwners, int *aOwners)
{
    *aPeople = 0; // Don't crash on bad read
    *aThigns = 0;
    *aOwners = 0;
    *allPeople = NULL;
    *allThings = NULL;
    *allOwners = NULL;

    if (1 != fread(nPeople, sizeof(*nPeople), 1, h)) return 0;
    *allPeople = malloc(sizeof(**allPeople) * *nPeople);
    if (!allPeople) return 0; // OOM
    *aPeople = *nPeople;
    if (*nPeople != fread(*allPeople, sizeof(**allPeople), nPeople, h)) return 0;

    if (1 != fread(nThings, sizeof(*nThings), 1, h)) return 0;
    *allThings = malloc(sizeof(**allThings) * *nThings);
    if (!allThings) return 0; // OOM
    *aThings = *nThings;
    if (*nThings != fread(*allThings, sizeof(**allThings), nThings, h)) return 0;

    if (1 != fread(nOwners, sizeof(*nOwners), 1, h)) return 0;
    *allOwners = malloc(sizeof(**allOwners) * *nOwners);
    if (!allOwners) return 0; // OOM
    *aOwners = *nOwners;
    if (*nOwners != fread(*allOwners, sizeof(**allOwners), nOwners, h)) return 0;

    return 1;
}

ヒープアリーナをディスクに直接書き込み、それを再度読み取るための古い手法がありました。絶対に使用せず、ポインタをディスクに保存しないことをお勧めします。そのように、セキュリティの悪夢があります。

メモリが安価だったときは、ブロック割り当てとリンクされたブロックを使用して、ディスク上のレコードを部分的に動的に更新する方法について話していました。しかし、このレベルで発生する問題については、気にしないで、すべてをRAMに読み込んで、再度書き戻すだけです。最終的には、データベースを学習します。データベースは、そのようなものを処理します。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Linux onARMのメモリマップドデバイスレジスタの書き込みと読み取り

分類Dev

Redis / java-バイナリデータの書き込みと読み取り

分類Dev

C ++、メモリの読み取りと書き込み、

分類Dev

EXIFデータの読み取りと書き込み

分類Dev

PDF / Aドキュメントでのxmlメタデータの読み取りと書き込み

分類Dev

データベースインデックス作成の書き込みと比較した読み取りの数

分類Dev

android-リアルタイムデータベースでの読み取りと書き込み

分類Dev

メモリリークと無効な読み取り/書き込み

分類Dev

Javaメモリモデル:揮発性物質と読み取り/書き込みの並べ替え

分類Dev

メモリの読み取りおよび書き込みバイト

分類Dev

クライアントサーバー方式で数値の二乗を取得するための共有メモリの書き込みと読み取り

分類Dev

読み取りメモリへの書き込みスペース

分類Dev

メモリの読み取り/書き込みアクセスエラー例外

分類Dev

OCamlのメモリマップトファイルへの書き込みと読み取り

分類Dev

メモリの読み取りと書き込みには、charデバイスよりもblockデバイスを使用する必要がありますか?

分類Dev

Q_PROPERTY:メンバーと読み取り/書き込み

分類Dev

データベースのIsolationLevelと読み取り/書き込みの問題

分類Dev

KotlinとFirebaseによるデータの読み取りと書き込み

分類Dev

CSV行の配列データの書き込みと読み取り

分類Dev

読み取りと書き込みの両方でブーストIOstreamメモリマップを開く方法

分類Dev

バイナリからの書き込みと読み取り

分類Dev

PySparkHDFSデータストリームの読み取り/書き込み

分類Dev

GSONを使用したデータの読み取りと書き込み

分類Dev

NFCの読み取り/書き込みとフラッター

分類Dev

ファイルアセンブリの読み取りと書き込み

分類Dev

Parsecでのストリーミングの読み取りと書き込み

分類Dev

マイクロサービスCQRSは、クエリモデルの構築(書き込み)とモデルの読み取りを分離します

分類Dev

ファイルストリームの読み取りと書き込みC ++

分類Dev

Dartのソケットデータとの間のバイト数の書き込み/読み取り

Related 関連記事

  1. 1

    Linux onARMのメモリマップドデバイスレジスタの書き込みと読み取り

  2. 2

    Redis / java-バイナリデータの書き込みと読み取り

  3. 3

    C ++、メモリの読み取りと書き込み、

  4. 4

    EXIFデータの読み取りと書き込み

  5. 5

    PDF / Aドキュメントでのxmlメタデータの読み取りと書き込み

  6. 6

    データベースインデックス作成の書き込みと比較した読み取りの数

  7. 7

    android-リアルタイムデータベースでの読み取りと書き込み

  8. 8

    メモリリークと無効な読み取り/書き込み

  9. 9

    Javaメモリモデル:揮発性物質と読み取り/書き込みの並べ替え

  10. 10

    メモリの読み取りおよび書き込みバイト

  11. 11

    クライアントサーバー方式で数値の二乗を取得するための共有メモリの書き込みと読み取り

  12. 12

    読み取りメモリへの書き込みスペース

  13. 13

    メモリの読み取り/書き込みアクセスエラー例外

  14. 14

    OCamlのメモリマップトファイルへの書き込みと読み取り

  15. 15

    メモリの読み取りと書き込みには、charデバイスよりもblockデバイスを使用する必要がありますか?

  16. 16

    Q_PROPERTY:メンバーと読み取り/書き込み

  17. 17

    データベースのIsolationLevelと読み取り/書き込みの問題

  18. 18

    KotlinとFirebaseによるデータの読み取りと書き込み

  19. 19

    CSV行の配列データの書き込みと読み取り

  20. 20

    読み取りと書き込みの両方でブーストIOstreamメモリマップを開く方法

  21. 21

    バイナリからの書き込みと読み取り

  22. 22

    PySparkHDFSデータストリームの読み取り/書き込み

  23. 23

    GSONを使用したデータの読み取りと書き込み

  24. 24

    NFCの読み取り/書き込みとフラッター

  25. 25

    ファイルアセンブリの読み取りと書き込み

  26. 26

    Parsecでのストリーミングの読み取りと書き込み

  27. 27

    マイクロサービスCQRSは、クエリモデルの構築(書き込み)とモデルの読み取りを分離します

  28. 28

    ファイルストリームの読み取りと書き込みC ++

  29. 29

    Dartのソケットデータとの間のバイト数の書き込み/読み取り

ホットタグ

アーカイブ