トップページ > 記事閲覧
圧縮したい
名前:にこよん 日時: 2017/09/04 01:35

こんばんは。 いつもお世話になっています。 FILE *fp; errno_t err; err = fopen_s(&fp, "SaveData\\data.sav", "wb"); //書き込みでファイルを開く fwrite(&fh, sizeof(file_header_t), 1, fp); //ファイルのヘッダ情報 fwrite(&clear_f, sizeof(int), 5, fp); //クリアフラグの保存 fwrite(&hash, sizeof(int), 1, fp); //ハッシュ値の保存 fclose(fp); //ファイルを閉じる このようなファイルへのデータの保存方法がありますが、 fcloseするまでは実際にファイルには書き込まれていないということを聞きました。 これと同じような使い方ができて書き込みの時に圧縮をかけて、読み込むときに解凍してくれる関数を作ることは可能でしょうか? zlibについていろいろ調べたのですが使い方が全く分かりませんでした。 つまりはバイナリ形式でデータを保存する時に圧縮をかけたいです。 できればファイルheaderの部分は圧縮をかけずに後半ののデータだけ圧縮したいですが、 かなり難しくなりそうなら考えないことにします。 visual C++ win10
メンテ

Page: 1 |

Re: 圧縮したい ( No.1 )
名前:管理人 日時:2017/09/05 01:17

> これと同じような使い方ができて書き込みの時に圧縮をかけて、読み込むときに解凍してくれる関数を作ることは可能でしょうか? fwrite を実行すると自動的に圧縮される( 且つヘッダーは圧縮されない )といった関数の作成は できないことはないかもしれませんが作るのは少し大変だと思います 圧縮するデータはあらかじめ malloc で確保したメモリ領域に memcpy などで書き込んでおいて、一括で圧縮をかけた後 fwrite でファイルに書き込むのが一番お手軽だと思います FILE *fp; errno_t err; err = fopen_s(&fp, "SaveData\\data.sav", "wb"); //書き込みでファイルを開く fwrite(&fh, sizeof(file_header_t), 1, fp); //ファイルのヘッダ情報 fwrite(&fh, sizeof(file_header_t), 1, fp); //ファイルのヘッダ情報 unsigned char *buffer = malloc( 64 * 1024 * 1024 ); // 保存するデータより十分大きいメモリを確保 int size = 0; // クリアフラグをメモリに書き込み memcpy( buffer + size, &clear_f, sizeof(int) * 5 ); size += sizeof(int) * 5; // ハッシュ値をメモリに書き込み memcpy( buffer + size, &hash, sizeof(int) ); size += sizeof(int); unsigned char *press_buffer = malloc( 64 * 1024 * 1024 ); // 圧縮データより十分大きいメモリを確保 int press_size; 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 buffer のデータを圧縮して press_buffer に格納、圧縮後のデータサイズを press_size に格納する処理 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 // 圧縮データのサイズを書き出し fwrite(&press_size, sizeof(int), 1, fp); // 圧縮データを書き出し fwrite(press_buffer, press_size, 1, fp); fclose(fp); //ファイルを閉じる // 確保したメモリの解放 free( buffer ); free( press_buffer ); > zlibについていろいろ調べたのですが使い方が全く分かりませんでした。 zlibは圧縮ライブラリの中でも簡単な方だと思いますので、こちらが分からないと圧縮処理を行うのは難しいかもしれません こちらのページ <zlib の使い方 矢田 晋> http://s-yata.jp/docs/zlib/ の、『一括圧縮・一括伸長』に書かれている compressBound, compress, uncompress の3つの関数を使用する方法が最も簡単だと思います ( 圧縮したいデータを malloc で確保したメモリに memcpy で書き込み → compress で圧縮 → fwrite で圧縮前のサイズの値と圧縮データをファイルに書き込み ) ただ、圧縮するデータが載せていただいたくらいのサイズ( int型変数 6個分 )だと、寧ろ圧縮後の方がデータサイズが大きくなってしまうかもしれません
メンテ
Re: 圧縮したい ( No.2 )
名前:にこよん 日時:2017/09/05 23:30

> 圧縮するデータはあらかじめ malloc で確保したメモリ領域に memcpy などで書き込んでおいて、一括で圧縮をかけた後 > fwrite でファイルに書き込むのが一番お手軽だと思います なんか少し前にそんな感じの記事見てあきらめた気がするのですがこれが一番簡単なんですか... > <zlib の使い方 矢田 晋> > の、『一括圧縮・一括伸長』に書かれている compressBound, compress, uncompress の3つの関数を使用する方法が最も簡単だと思います ありがとうございます。読んでみます。 この流れで頑張ってみます。 > ただ、圧縮するデータが載せていただいたくらいのサイズ( int型変数 6個分 )だと、寧ろ圧縮後の方がデータサイズが大きくなってしまうかもしれません サンプルで全てコピペすると邪魔かと思い一部省きました。 アイテムの情報(ほとんどが0の時が多い構造体)を大量に保存するので圧縮したいなと... 実際のサイズは12.4MBですが普通に圧縮すると30KBになるんですよね。 セーブスロットを100個用意しているので約1GBも消費してしまいます。 今週の土日ぐらいに再挑戦してみます。
メンテ
Re: 圧縮したい ( No.3 )
名前:yumetodo 日時:2017/09/10 16:00

ちなみにzlib圧縮はboost.iostreamsを使うとかなり楽に圧縮解凍できたりするので、zlibをリンクしたboostを用意できるならそれを使う手もあります
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存