RandomAccessFile - возвращает пустую строку - PullRequest
0 голосов
/ 20 марта 2012

У меня есть файл фиксированного формата.

Я хочу получить доступ к определенным строкам в этом файле на основе номеров строк.

например. читать строку 100

Длина каждой строки составляет 200 байтов.

Таким образом, прямое перемещение курсора к 100-й строке с использованием RandomAccessFile будет выглядеть так:

File f = new File(myFile);
RandomAccessFile r = new RandomAccessFile(f,"rw");
r.skipBytes(200 * 99);   // linesize * (lineNum - 1)
System.out.println(r.readLine());

Однако, я получаю вывод как ноль.

Что мне здесь не хватает?

Этот вопрос является продолжением ответа на мой предыдущий вопрос Достижение определенной строки в файле с помощью RandomAccessFile

Обновление:

Ниже программа работает точно так, как я ожидаю:

Размер строки составляет 200 символов.

File f = new File(myFile);
RandomAccessFile r = new RandomAccessFile(f,"rw");
r.seek(201 * (lineNumber-1));   // linesize * (lineNum - 1)
System.out.println(r.readLine());

При вводе номера белья (любой номер строки из всего файла) печатается эта строка.

@ EJP: Пожалуйста, объясните!

Ответы [ 4 ]

1 голос
/ 20 марта 2012

Во-первых, если вы собираетесь только читать из файла, а не записывать в него, я бы посоветовал открыть файл RandomAccessFile как «r», а не «rw».Причина в том, что, если файл открыт для предоставления доступа на запись, вы можете фактически переместить указатель в файле в место, которое больше длины файла, потому что вы можете потенциально написать файл настолько большого размера, насколько вам нужно.

Например, если у вас есть файл длиной 100 байт, открытие его в режиме только для чтения заставит вас держать указатель где-то в этих 100 байтах.Однако, если вы открываете тот же файл в режиме чтения-записи, вы можете указать RandomAccessFile искать (250), и он будет подчиняться без каких-либо проблем, так как считает, что вы потенциально хотите записать данные в этот момент в файле.

Итак, как утверждали некоторые другие, вполне возможно, что вы перешли за конец файла, что вполне допустимо в режиме «rw».

Во-вторых, если вы собираетесьчитать с начала файла, я бы порекомендовал вам использовать seek (), а не skipBytes ().Используя seek (), вы гарантируете, что вы перемещаетесь в то место, где вы хотите быть, поскольку оно всегда относительно начала файла.Однако skipBytes () относится к текущей позиции указателя в файле, поэтому, если вы случайно переместили указатель где-то в своем коде между конструктором RandomAccessFile и вызовом метода skipBytes (), вы не окажетесь в правильном месте.

Итак, если вы собираетесь работать с начала файла, seek () обеспечил более высокий уровень безопасности, который вы в конечном итоге получите в правильном месте в файле, независимо от того, чтоиначе вы делаете для RandomAccessFile.

1 голос
/ 20 марта 2012

RandomAccessFile.readLine() возвращает ноль в конце файла.Как говорится в Javadoc.

Итак, вы находитесь в конце файла.

Так что ваши вычисления, которые говорят иначе, неверны.

0 голосов
/ 20 марта 2012

То, что EJP сказал правильно: http://docs.oracle.com/javase/6/docs/api/java/io/RandomAccessFile.html

  • подтвердите, что вы должны исправить файл.Создание файла RandomAccessFile с несуществующим файлом вызовет исключение.Поскольку у вас нет исключения, вы создали файл RandomAccessFile с файлом A.Убедитесь, что он правильный.
  • RandomAccessFile использует внутренний указатель позиции файла.Если вы уже в конце файла и пропустите несколько байтов снова, это объяснит поведение, которое вы упомянули.Пожалуйста, убедитесь, что вы находитесь в правильном месте в файле.
0 голосов
/ 20 марта 2012
byte[] line = new byte[200];
r.seek(200 * 99);
r.read(line);
String s = new String(line, "UTF-8"); // Or probably "Cp1252"
...