0

以前、私は質問をしました。

問題は、ファイル構造の要求が非常に高いことです。

たとえば、最大 4500 個のファイルと 500 MB のデータを含むコンテナーを作成しようとしています。

このコンテナのファイル構造は、

  • SQLite DB (1MB 以下)
  • テキストベースの xml に似たファイル
  • 残りの 4,500 個のファイルを構成する動的フォルダー構造内の画像

  • 最初の作成後、画像ファイルは削除を除いて読み取り専用です。

  • 小さなデータベースは、コンテナにアクセスするときに定期的に使用されます。

Tar、Zipなどはすべて遅すぎます(圧縮が0であっても)。遅いというのは主観的なものですが、このサイズのコンテナーを untar するには 20 秒以上かかります。

何かご意見は?

4

6 に答える 6

1

コンテナーで任意のファイル システム操作 (コンテナー内の新しいファイルの作成、削除、既存のファイルの上書き、追加など) を行っているように見えるので、何らかのファイル システムを使用する必要があると思います。大きなファイルを割り当て、その中にファイル システム構造を作成します。

利用可能なファイル システムにはいくつかのオプションがあります。Berkeley UFS と Linux ext2/ext3 の両方で、利用可能なユーザー モード ライブラリがあります。また、FAT の実装がどこかにある可能性もあります。ファイル システムの構造を理解していることを確認し、拡張可能なものを選択してください。ext2 は (別のブロック グループによって) かなり簡単に拡張できますが、FAT は拡張が困難です (FAT に追加する必要があります)。

または、ファイル システムの下に仮想ディスク フォーマットを配置して、ブロックを任意に再マッピングすることもできます。これにより、ファイル システムの「空き」ブロックをディスクに表示する必要がなくなり、実際のコンテナ ファイルよりもはるかに大きな仮想ディスクを割り当てることができます。

于 2008-11-03T05:29:52.180 に答える
0

ファイルへの読み取り専用アクセスのみが必要であるという前提で作業し、ファイルをすべてマージして、ファイル名を示す2番目の「インデックス」ファイル(またはヘッダー内のインデックス)を作成して、開始します。位置と長さ。開始点を探して正しいバイト数を読み取るだけです。方法は言語によって異なりますが、ほとんどの言語で非常に簡単です。

次に、最も難しい部分は、データファイルとインデックスの作成になります。それでもかなり基本的なことです。

于 2008-11-03T03:24:38.360 に答える
0

ISOディスクイメージでうまくいくかもしれません。その数のファイルを簡単に保持できるはずであり、すべての主要なオペレーティングシステム上の多くのソフトウェアによってサポートされています。

于 2008-11-03T04:05:06.687 に答える
0

Solid File Systemを確認してください- 必要なもののようです。

于 2008-12-20T10:49:46.157 に答える
0

三つのこと。

1) ティモシー・ウォルターズが言ったことは正しかったので、詳しく説明します。

2) 4500 個のファイルと 500Mb のデータは、単純に大量のデータとディスクへの書き込みです。データセット全体を操作している場合は、遅くなります。I/O の真実だけです。

3)他の人が述べたように、ユースケースの詳細はありません。

読み取り専用のランダム アクセス シナリオを想定すると、Timothy の言うことはほとんど役に立たず、実装は簡単です。

一言で言えば、これがあなたがすることです。

すべてのファイルを 1 つの BLOB に連結します。それらを連結している間、それらのファイル名、ファイル長、およびファイルが blob 内で開始するオフセットを追跡します。その情報を、名前でソートされたデータのブロックに書き出します。これを目次または TOC ブロックと呼びます。

次に、2 つのファイルを連結します。単純なケースでは、最初に TOC ブロックがあり、次にデータ ブロックがあります。

この形式からデータを取得する場合は、TOC でファイル名を検索し、データ ブロックの先頭からのオフセットを取得し、TOC ブロック サイズを追加して、FILE_LENGTH バイトのデータを読み取ります。単純。

賢くしたい場合は、TOC を blob ファイルの末尾に置くことができます。次に、TOC の先頭へのオフセットを最後に追加します。次に、ファイルの最後まで lseek し、4 または 8 バイト (数値のサイズに応じて) バックアップし、その値を取得して、TOC の先頭までさらに lseek します。その後、振り出しに戻ります。これにより、最初にアーカイブを 2 回再構築する必要がなくなります。

TOC をブロック (たとえば 1K バイトのサイズ) でレイアウトすると、TOC でバイナリ検索を簡単に実行できます。各ブロックにファイル情報エントリを入力するだけで、スペースがなくなったらマーカーを書き、ゼロを埋めて次のブロックに進みます。二分検索を行うには、TOC のサイズがわかっているので、途中から開始し、最初のファイル名を読み取り、そこから開始します。すぐにブロックが見つかるので、ブロックを読み込んでファイルをスキャンします。これにより、RAM に TOC 全体がなくても効率的に読み取ることができます。もう 1 つの利点は、TAR (何かを見つけるためにアーカイブをクロールする必要がある場合) のようなチェーン スキームよりも、ブロッキングに必要なディスク アクティビティが少ないことです。

ファイルをブロックサイズに合わせてパディングすることをお勧めします。ディスクは通常のサイズのデータ​​ブロックで動作しますが、これも難しくありません。

全体を再構築せずにこれを更新するのは困難です。更新可能なコンテナー システムが必要な場合は、単純なファイル システムの設計を検討することもできます。

移植性に関しては、2 進数をネットワークの順序で保存することをお勧めします。ほとんどの標準ライブラリには、これらの詳細を処理するためのルーチンが用意されているためです。

于 2008-11-03T04:44:53.473 に答える
0

まず、質問を拡大していただきありがとうございます。より良い回答を提供するのに大いに役立ちます。

いずれにせよ SQLite データベースが必要になることを考えると、データベースにすべてを入れた場合のパフォーマンスを見たことがありますか? 私の経験は SQL Server 2000/2005/2008 に基づいているため、SQLite の機能については肯定的ではありませんが、削除を可能にしながら、レコードを検索してデータを取得するための非常に高速なオプションになると確信しています。および/または更新オプション。

通常、データベース内にファイルを配置することはお勧めしませんが、すべての画像の合計サイズが 4,500 枚の画像で約 500MB であることを考えると、画像ごとに 100K を少し超えていますよね? 画像を保存するために動的パスを使用している場合、もう少し正規化されたデータベースでは、各パスを ID にマップする「ImagePaths」テーブルを作成できます。その場合、その PathID を持つ画像を探して、そこからデータをロードできます。必要に応じて BLOB 列。

XML ファイルは SQLite データベースにある場合もあります。これにより、Windows と OSX の間で問題なく移動できるアプリ用の単一の「データ ファイル」が得られます。必要なパフォーマンスと互換性を提供するために、SQLite エンジンに頼ることができます。

どのように最適化するかは、使用状況によって異なります。たとえば、特定のパスにあるすべての画像を頻繁に取得する必要がある場合は、PathID (パフォーマンスの整数として) を使用すると高速ですが、開始するすべての画像を表示している場合「A」を使用してパスをプロパティとして表示すると、ImageName 列のインデックスがより便利になります。

私はこれが時期尚早の最適化のように聞こえることを少し心配しています.「十分に速く」動作するソリューションを見つける必要があり、そのメカニズムを抽象化して、アプリケーション(またはMacとPCの両方のバージョンがある場合は両方のアプリ)が使用できるようにする必要があります.単純なリポジトリなどを使用すると、アプリケーションに影響を与えることなく、保存/取得方法を自由に変更できます。

于 2008-11-04T06:01:11.210 に答える