2012-01-19 3 views
1

Я пытаюсь создать файл случайного доступа в java. Я пишу что-то в новой строке.Как я могу вернуть адрес строки в файле произвольного доступа?

  1. Как я могу вернуть адрес этой строки на Java?

Кроме того, я немного смущен RAF.

Например у меня есть файл, который состоит из следующих записей в алфавитном порядке

Джордж 10 10 8

Mary 9 10 10

Nick 8 8 8

Nickolas 10 10 9

Я хотел бы вернуть оценки Николаса. Как я могу объявить это в RAF?

Есть ли способ, который может «читать (« Николас »)» и вернуть мне линию?

Спасибо, заранее

+0

Вы должны его искать самостоятельно. Нет волшебства. Я бы предложил использовать только «BufferedReader» и игнорировать любую строку, которая не соответствует шаблону, и перейти к следующему. – BalusC

ответ

3

Файлы случайного доступа обычно содержат двоичные данные, а не данные ascii (например, обычный текст). Пример, который вы показываете, - ascii.

Поскольку данные являются ascii, это означает, что нелегко искать различные места в файле. На самом деле, как правило, подход, чтобы получить оценки для Николаса, состоял в том, чтобы прочитать файл по строке и разделить каждую строку на столбцы. Затем сравните первый столбец для Николаса.

Например,

 

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(); 
} 
 

EDIT:

Есть несколько способов, чтобы ускорить это. Вот три:

хранение всех данных в HashMap

Если вы не слишком много записей, или если каждая запись не занимает много места, вы можете прочитать их все в оперативную память. Вы также можете использовать 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(); 
} 
 

Теперь поиск будет очень быстрым.

Использования бинарного поиска

Если у вас слишком много записей, чтобы поместиться в памяти, вы можете написать все студенческие данные случайного доступа (двоичный файл). Здесь у вас есть несколько вариантов: вы можете сделать каждую запись по-разному, или вы можете сделать каждую запись фиксированной длиной. Фиксированные записи длины легче для некоторых видов поиска, например, для двоичных запросов.

Например, если вы знаете, что каждая запись составляет 100 байт, то вы знаете, как добраться до n-й записи в двоичном файле, хранящем записи. В принципе, прочитайте 99 * n байтов. Затем следующие 100 байт являются 100-й записью.

Таким образом, если записи отсортированы по имени студента, вы можете очень легко использовать двоичный поиск, чтобы найти конкретного ученика. Этот подход будет по-прежнему быстрым, хотя и не таким быстрым, как структура данных на основе RAM.

Использование HashMap в качестве индекса

Еще одним вариантом является сочетание этих двух подходов я уже упоминал выше. Запишите данные в двоичный файл и сохраните смещения байта записей в хэш-карте. Хэш-карта может использовать имя студента в качестве ключа, как и раньше, но затем сохраняет длинное целочисленное смещение к записи в файле произвольного доступа. Таким образом, чтобы найти конкретного ученика, вы найдете смещение байта с помощью хэш-карты, а затем «ищите» запись в файле, а затем прочитайте ее. Этот последний подход работает, даже если записи различаются по длине.

+0

Спасибо за ответ. Разве это не будет стоить нам много? В школе может быть 1000 учеников, поэтому мне нужно искать 1000 записей. – programmer

+0

Ну, у меня может быть 10000 записей не только 1000 – programmer

+0

Кроме того, могу ли я написать имена и оценки студентов в двоичном формате? – programmer

2

Там нет такого понятия, как «линия». Существуют, однако, разделители строк (новая строка, которая равна '\n'). Вы можете написать строку, но это только записывает данные, за которыми следует новая строка. Вы можете прочитать строку, но опять же, которая читает только до тех пор, пока не найдет символ новой строки или конец файла.

Так, чтобы найти линии п, вы должны продолжать читать, пока вы не подсчитывали п-1 символы новой строки, и продолжайте чтение, пока не найдете следующий (или конец файла).

+0

Спасибо за ответ. Так что я буду хранить где-нибудь номер строки для каждого ученика, чтобы сразу найти его в файле, правильно? Есть ли какой-нибудь метод в Java, который возвращает строку в RAF? – programmer

+1

Нет, просто напишите функцию поиска, которая найдет строку, начинающуюся с данной строки, и вызовет ее каждый раз. Это будет дорого, если вы его часто используете (это операция O (n)), поэтому вы можете написать метод, который читает файл один раз и создает из него структуру данных, а затем другой метод, который записывает всю структуру обратно в файл. – Joe

Смежные вопросы