2013-02-26 11 views
5

Ich möchte Datei Zeile für Zeile lesen. BufferedReader ist viel schneller als RandomAccessFile oder BufferedInputStream. Aber das Problem ist, dass ich nicht weiß, wie viele Bytes ich lese. Wie kann man Bytes lesen (Offset)? Ich habe es versucht.Wie kann man Bytes lesen (Offset) von BufferedReader?

String buffer; 
int offset = 0; 

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

Ich arbeite, wenn die Datei klein ist. Wenn die Datei jedoch groß wird, wird der Offset kleiner als der tatsächliche Wert. Wie kann ich Offset bekommen?

+0

Welche größere Aufgabe versuchen Sie zu erreichen? Es ist grundlegend schwierig wegen des internen Puffers (und Codierungen und verschiedenen Zeilenenden). –

+0

Ich möchte Offsets von Zeilenbeginn erhalten. Also verwende ich diese Offsets, um später einen Teil der Datei mit RandomAccessFile zu lesen. – user1301568

+0

Sie nehmen an, dass es nur ein Zeilentrennzeichenbyte gibt, z. \ n. Kannst du das annehmen? – EJP

Antwort

-3

Wenn Sie eine Datei Zeile für Zeile lesen möchten, würde ich diesen Code empfehlen:

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

ich immer diese Methode in der Vergangenheit verwendet, und funktioniert super!

Quelle: Here

+2

Sie antworten, es ist ein bisschen falsch, weil Sie externe Ressourcen in einem endgültigen Block schließen sollten, auch Sie die Frage nicht beantworten, und neben diesem verwendet er etwas ähnliches, aber mit einem kompakteren Codebeispiel. – comanitza

+0

Wenn es von Rose Indien kommt, sollten Sie davon ausgehen, dass es nur größtenteils richtig ist. Sie lesen besser jede andere Website. –

8

Es gibt keine einfache Möglichkeit, dies mit BufferedReader wegen zwei Effekten zu tun: Charakter endcoding und Zeilenende. Unter Windows lautet die Zeilenendung \r\n, also zwei Byte. Unter Unix ist das Zeilentrennzeichen ein einzelnes Byte. BufferedReader wird beide Fälle ohne Sie zu beachten, so dass Sie nach readLine() nicht wissen, wie viele Bytes übersprungen wurden.

Auch buffer.getBytes() gibt nur das korrekte Ergebnis zurück, wenn Ihre Standardcodierung und die Codierung der Daten in der Datei zufällig identisch ist. Bei der Verwendung byte[] < ->String Umwandlung aller Art sollten Sie immer genau angeben, welche Codierung verwendet werden sollte.

Sie können auch keine Zählung InputStream verwenden, da die gepufferten Leser Daten in großen Blöcken lesen. Nach dem Lesen der ersten Zeile mit beispielsweise 5 Bytes würde der Zähler im inneren InputStream 4096 zurückgeben, weil der Leser immer so viele Bytes in seinen internen Puffer liest.

Sie können sich NIO dafür ansehen. Sie können einen niedrigen Wert ByteBuffer verwenden, um den Offset zu verfolgen und ihn in einen CharBuffer umzuwandeln, um die Eingabe in Zeilen zu konvertieren.

+0

Es gibt keine einfache Möglichkeit, dies mit BufferedReader zu tun, da es sowohl Pufferung als auch Erkennung neuer Zeilen durchführt. Übrigens, danke für Hinweise zu ByteBuffer und CharBuffer –

0

Ich frage mich Ihre endgültige Lösung, aber ich denke, mit langen Typ anstelle von Int kann die meisten Situation in Ihrem Code oben treffen.

Verwandte Themen