2013-02-26 3 views
5

Я хочу прочитать файл по строкам. BufferedReader намного быстрее, чем RandomAccessFile или BufferedInputStream. Но проблема в том, что я не знаю, сколько байтов я прочитал. Как узнать прочитанные байты (смещение)? Я пробовал.Как узнать байты чтения (смещения) BufferedReader?

String buffer; 
int offset = 0; 

while ((buffer = br.readLine()) != null) 
    offset += buffer.getBytes().length + 1; // 1 is for line separator 

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

+0

Какую большую задачу вы пытаетесь достичь? Это принципиально сложно из-за внутреннего буфера (и кодирования, и разных строк). –

+0

Я хочу получить смещения начала линий. Итак, я использую эти смещения, чтобы позже прочитать часть файла, используя RandomAccessFile. – user1301568

+0

Вы считаете, что существует только один разделитель строк, например. \ П. Можете ли вы предположить это? – EJP

ответ

-3

Если вы хотите, чтобы прочитать файл построчно, я рекомендовал бы этот код:

import java.io.*; 
class FileRead 
{ 
public static void main(String args[]) 
    { 
    try{ 
    // Open the file that is the first 
    // command line parameter 
    FileInputStream fstream = new FileInputStream("textfile.txt"); 
    // Use DataInputStream to read binary NOT text. 
    BufferedReader br = new BufferedReader(new InputStreamReader(fstream)); 
    String strLine; 
    //Read File Line By Line 
    while ((strLine = br.readLine()) != null) { 
    // Print the content on the console 
    System.out.println (strLine); 
    } 
    //Close the input stream 
    in.close(); 
    }catch (Exception e){//Catch exception if any 
    System.err.println("Error: " + e.getMessage()); 
    } 
    } 
} 

Я всегда использовал этот метод в прошлом, и отлично работает!

Источник: Here

+2

. Ответ вы немного ошибаетесь, потому что вы должны закрыть внешние ресурсы в блоке finally, также вы не отвечаете на вопрос, а кроме того он использует что-то подобное, но с более компактным примером кода. – comanitza

+0

Если это исходит от розы, вы должны предположить, что это только в основном право. Вам лучше читать практически любой другой веб-сайт. –

8

Там нет простого способа сделать это с BufferedReader из-за два эффектами: Характер endcoding и окончание строк. В Windows окончание строки - \r\n, которое составляет два байта. В Unix разделитель строк представляет собой один байт. BufferedReader будет обрабатывать оба случая, если вы не заметите, поэтому после readLine() вы не будете знать, сколько байтов было пропущено.

Также buffer.getBytes() возвращает правильный результат, когда ваше кодирование по умолчанию и кодирование данных в файле случайно совпадают. При использовании byte[] < ->String конверсии любого типа, вы должны всегда указать, какую именно кодировку следует использовать.

Вы также не можете использовать подсчет InputStream, потому что буферизованные считыватели читают данные в больших кусках. Поэтому после прочтения первой строки, скажем, 5 байтов, счетчик во внутреннем InputStream вернет 4096, потому что читатель всегда читает, что многие байты во внутреннем буфере.

Вы можете взглянуть на NIO для этого. Вы можете использовать низкий уровень ByteBuffer, чтобы отслеживать смещение и обертывание в CharBuffer для преобразования ввода в строки.

+0

Нет простого способа сделать это с помощью BufferedReader, поскольку он выполняет как буферизацию, так и новое обнаружение линии. BTW, спасибо за намек на ByteBuffer и CharBuffer –

0

Мне интересно ваше окончательное решение, однако, я думаю, что использование длинного типа вместо int может удовлетворить наибольшую ситуацию в вашем коде выше.

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