3

私が行っているこの大学のプロジェクト (過去にいくつか投稿したことがあります) は、ある種のソーシャル ネットワークであり、ユーザーがメッセージを交換する機能が必要です。

最初に、すべてのメッセージをリンク リストに保持するようにデータ構造を設計し、メッセージ サイズを 256 文字に制限しました。ただし、メッセージをディスクに保存し、必要なときにのみ読む方が、講師の好みになると思います。もちろん、彼らは彼らが何を好むかは言いません。

覚えておくべきことの 1 つは、各ユーザーからの最新の 20 件のメッセージを保存するだけでよく、それ以上保存する必要はないということです。

現在、受信トレイとして機能するハッシュ テーブルがあり、これはユーザー プロファイル内にあります。このハッシュ テーブルは、名前 (メッセージを送信したユーザー) によってインデックスが作成されます。各要素の値は、20 個のsize_t要素 (上で述べたように 20 個のメッセージ) の配列を保持するデータ構造になります。アイデアは、ディスク ファイルのオフセットと書き込まれたバイトを追跡することです。次に、メッセージを読み取る必要がある場合はfseek()、必要なバイトを使用して読み取るだけです。

これはうまくいくと思います...ネットワーク内のすべてのユーザーからのすべてのメッセージを保持するために、1 つのファイルだけを使用できます。同僚が各ユーザーからのメッセージを個別に保存することについてインストラクターに尋ねたので、ファイルシステムに制限があるため、それは最善のアプローチではない可能性があると答えたので、1つのファイルと言っています。だからこそ、私はシングルファイルルートに行くことを考えています。

ただし、これには問題があります...最新の 20 件のメッセージのみを保存する必要があるため、この制限に達すると古いメッセージを破棄する必要があります。

これを行う方法がわかりません...私が知っているのはfread()fwrite()ファイルとの間でバイトを読み書きすることだけです。ファイルオフセットに移動して、「ねえ、次のXバイトを削除してください」と言うにはどうすればよいですか? それができたとしても、別の問題があります...それより下のすべてのオフセットは完全に異なり、問題を解決するにはすべてのユーザーのメールボックスを処理する必要があります。どれが苦痛だろう...

それで、私の問題を解決するための提案はありますか?何を指示してるんですか?

4

3 に答える 3

2

ファイルの途中から任意にバイトを削除することはできません。機能する唯一の方法は、それらなしでファイル全体を書き直すことです。このようにすることが良い考えかどうかという問題を無視して、固定長のフィールドがある場合、1 つの解決策は、最も古いメッセージを最新のメッセージで上書きすることです。そうすれば、ディスク上のメッセージのサイズ/位置は変更されないため、他のオフセットは影響を受けません。

編集: 外部ライブラリの使用が許可されている場合は、単純なSQLite db を作成することが適切な解決策になる可能性があります。

于 2010-04-12T00:24:18.320 に答える
0

完全を期すために、別の解決策を提案したいと思います。

文字列はヌルバイト文字 で終わる必要がある"hello world\0"ため、生のバイナリ データを に到達するまで読み取ることができます"\0"。他のデータ型には固定ビットがあり、バイトオーダー (エンディアン) に注意してください。

また、各メッセージの前にペイロードを定義して、その文字列の長さを知ることもできます。

"11hello world;2hi;15my name is loco"

したがって、生のスニペットをデータ フィールドのように扱うことができます。

于 2013-02-18T11:06:55.643 に答える
0

必要以上に人生を複雑にしています。

メッセージが 256 文字の場合は、256 文字の配列を使用して各メッセージを保持します。

fwrite でディスクに書き込み、fread で読み取り、文字列の最初の文字を \0 に変更して削除し (またはその他の好きな文字列)、それをディスクに書き込みます。

メッセージのインデックスを単純な構造 (ユーザー名/recno) に保持し、fseek を使用してファイル内を移動します。新しいレコードを書き込むときに次の空きレコードをブルート フォースする (ファイルの先頭から読み取りを開始し、\0 を押すと停止する) か、空きレコードのインデックスを配列に保持し、書き込み時にそれらの 1 つを取得することができます。新しいもの (または、配列が空の場合は、ファイルの最後まで fseek し、完全な新しいレコードを書き込みます。)

于 2010-04-12T00:28:40.577 に答える