通常、ランダム アクセス ファイルには、ASCII (プレーン テキストなど) データではなく、バイナリ データが含まれます。あなたが示している例はasciiです。
データは ASCII であるため、ファイル内のさまざまな場所を探すのは簡単ではありません。実際、Nickolas の成績を取得する一般的なアプローチは、ファイルを 1 行ずつ読み取り、各行を列に解析することです。次に、ニコラスの最初の列を比較します。
例えば、
BufferedReader in = new BufferedReader(new FileReader("grades.txt"));
String line = in.readLine();
while(null != line) {
String [] columns = line.split(" ");
if( columns[0].equals("Nickolas") )
System.out.println("I found the line! " + line);
line = in.readLine();
}
編集:
これを高速化する方法はいくつかあります。次の 3 つがあります。
すべてのデータを HashMap に格納する
レコードが多すぎない場合、または各レコードが多くのスペースを必要としない場合は、それらすべてを RAM に読み込むことができます。HashMap を使用して、生徒の名前を記録にマップすることもできます。例えば:
HashMap<String, Student> grades = new HashMap<String, Student>();
BufferedReader in = new BufferedReader(new FileReader("grades.txt"));
String line = in.readLine();
while(null != line) {
String [] columns = line.split(" ");
grades.put( column[0],
new Student( /* create student class instance from columns */ );
line = in.readLine();
}
これで、ルックアップが非常に高速になります。
二分探索の使用
レコードが多すぎて RAM に収まらない場合は、すべての学生データをランダム アクセス (バイナリ) ファイルに書き込むことができます。ここでは、いくつかのオプションがあります。各レコードの長さを変更するか、各レコードを固定長にすることができます。固定長レコードは、バイナリ検索など、ある種の検索では簡単です。
たとえば、各レコードが 100 バイトであることがわかっている場合、レコードを格納しているバイナリ ファイルの n 番目のレコードに到達する方法がわかります。基本的に、99*n バイトを読み取ります。次の 100 バイトは 100 番目のレコードです。
したがって、レコードが学生名でソートされている場合、バイナリ検索を使用して特定の学生を非常に簡単に見つけることができます。このアプローチは、RAM ベースのデータ構造ほど高速ではありませんが、依然として高速です。
HashMap をインデックスとして使用する
さらに別のオプションは、前述の 2 つのアプローチを組み合わせることです。データをバイナリ ファイルに書き込み、レコードのバイト オフセットをハッシュ マップに格納します。ハッシュ マップは、以前と同様に学生の名前をキーとして使用できますが、ランダム アクセス ファイル内のレコードへの長整数オフセットを格納します。したがって、特定の学生を検索するには、ハッシュ マップを使用してバイト オフセットを見つけ、ファイル内のレコードを「シーク」してから読み取ります。この最後のアプローチは、レコードの長さが異なる場合でも機能します。