2016-05-29 9 views
0

Gibt es eine Möglichkeit, von einem BufferedReader zu lesen, bis es ein Zeichen erreicht, das nicht Newline oder Return-Wagen ist (was ist readLine())?BufferedReader - gelesen von Token anstelle von readLine()?

Ich möchte nicht eine Zeile lesen und dann teilen. Ich möchte Zeilenumbrüche ignorieren und Wagen zurückgeben und nur ein bestimmtes Token (z. B. Tab) mit der Leistung von BufferedReader berücksichtigen.

+1

Sie können Ihren BufferedReader in einen Scanner einpacken. – matt

Antwort

0

das ist nicht sehr elegant, aber kann funktionieren.

  1. kopiere openjdk BufferedReader-Quelle in ein anderes Paket (JVM lässt deinen Classloader keine Standard-Java-Klasse überschreiben). Sie können es von hier erhalten - http://grepcode.com/file_/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/io/BufferedReader.java/?v=source
  2. Erstellen Sie eine Unterklasse, die von dieser BufferedReader-Kopie erstreckt, erstellen Sie die Konstruktoren und überschreiben Sie readLine(). Kopieren der ursprüngliche readline() Umsetzung und fügt als die überschriebenen readline()
  3. Änderung alle Attribute und Methoden aus der übergeordneten Klasse (BufferedReeader), die die Zusammenstellung von privaten blockieren zu geschützten
  4. ersetzen alle Erwähnungen \ n und] r in der Unterklasse readline() t \ statt (so du wird Split von Tab)

voilà :-)

dies ist, wie es am Ende aussehen wird

import java.io.IOException; 
import java.io.Reader; 

public class MyBufferedReader extends BufferedReader { 

    /** 
    * 
    * @param in 
    */ 
    public MyBufferedReader(Reader in) { 
     super(in); 

    } 

    @Override 
    String readLine(boolean ignoreLF) throws IOException { 
     StringBuffer s = null; 
     int startChar; 

     synchronized (lock) { 
      ensureOpen(); 
      boolean omitLF = ignoreLF || skipLF; 

     bufferLoop: 
      for (;;) { 

       if (nextChar >= nChars) 
        fill(); 
       if (nextChar >= nChars) { /* EOF */ 
        if (s != null && s.length() > 0) 
         return s.toString(); 
        else 
         return null; 
       } 
       boolean eol = false; 
       char c = 0; 
       int i; 

       /* Skip a leftover '\n', if necessary */ 
       if (omitLF && (cb[nextChar] == '\t')) 
        nextChar++; 
       skipLF = false; 
       omitLF = false; 

      charLoop: 
       for (i = nextChar; i < nChars; i++) { 
        c = cb[i]; 
        if (c == '\t') { 
         eol = true; 
         break charLoop; 
        } 
       } 

       startChar = nextChar; 
       nextChar = i; 

       if (eol) { 
        String str; 
        if (s == null) { 
         str = new String(cb, startChar, i - startChar); 
        } else { 
         s.append(cb, startChar, i - startChar); 
         str = s.toString(); 
        } 
        nextChar++; 
        if (c == '\t') { 
         skipLF = true; 
        } 
        return str; 
       } 

       if (s == null) 
        s = new StringBuffer(defaultExpectedLineLength); 
       s.append(cb, startChar, i - startChar); 
      } 
     } 
    } 

} 

Sie es wie diese

MyBufferedReader my = new MyBufferedReader(new InputStreamReader(Main.class.getResourceAsStream("fileWithTabs.txt"))); 
    String line = null; 
    while((line = my.readLine())!=null) { 
     System.out.println(line); 
    } 
    my.close(); 

für eine Eingabe wie diese jedoch

some string some other string 
some third string after a newline some forth 
and so on 

Ergebnis ist

some string 
some other string 
some third string after a newline 
some forth 

and so on 

verwenden können, sieht aus wie eine sehr, sehr umständlich Lösung, so würde ich wirklich gerne andere clever Antworten hier zu sehen

1

Ja sicher.

BufferedReader br = ... 
StringBuilder sb = new StringBuilder(ESTIMATED_LENGTH); 
int ch; 
while ((ch = br.read()) != -1 && ch != '\t') { 
    sb.append(ch); 
} 

Im besten Fall werden Sie die Leistung erhalten, die als fast so gut wie BufferedReader.readLine() ist. Im schlimmsten Fall führst du ein bis zwei zusätzliche Kopien der Charaktere aus (denke ich) ... was nicht schlecht ist, ist ein Leistungshit .

Wenn Sie eine so gute Leistung wie BufferedReader erzielen möchten, müssen Sie den Code BufferedReader selbst hacken ... oder ihn neu schreiben.

(Ihr Versuch der Erweiterung BufferedReader funktioniert nicht, weil Sie private Methoden von der übergeordneten Klasse aufrufen. Das ist nicht erlaubt! Wenn Sie "beheben", indem Sie den Methodenzugriff ändern, dann können Sie auch nur „Klon“ der BufferedReader Klasse und Ihre Methoden, um es hinzuzufügen natürlich Ihre Klasse ist nicht mehr ein java.io.BufferedReader oder eine Unterklasse davon)


1 -.. die Begründung, das große Bild betrachten.Wenn Sie große Datenmengen von irgendwo lesen, ist der Leistungsengpass wahrscheinlich entweder I/O oder was Sie mit den Token tun, nachdem Sie sie gelesen haben. Wenn das nicht der Fall ist, sollten Sie wahrscheinlich 1) java.nio/CharBuffer, 2) einen benutzerdefinierten E/A-Stack oder 3) eine andere Programmiersprache verwenden.

+0

tatsächlich, Schritte 1 bis 4 zeigen, dass ich mit einer Kopie von BufferedReader arbeiten und alle privaten Attribute und Methoden wurden in geschützten (Schritt 3) geändert – Leo

1

Für so etwas sollten Sie nicht einmal BufferedReader verwenden. Ich würde NIO verwenden wie so:

public String[] splitContentsBy(String split, File file){ 
    try{ 
     byte[] bytes = Files.readAllBytes(file); 
     String contents = new String(bytes); 
     String[] array = contents.spilt(split); 
    }catch(IOException e){ 
     e.printStackTrace(); 
    } 
} 

Wenn Sie nur ein Zeichen möchten, können Sie haben:

char c = '?'; //A question mark, as an example. 
String[] parts = splitContentsBy(String.valueOf(c), new File("file.txt"); 
+0

Nun, ich stimme zu, dass das Problem löst, aber möglicherweise keine gute Idee für ein groß genug Textdatei (wie zum Beispiel Serverprotokolle) – Leo

0

die neue Zeile zu ignorieren und nur geben Sie Ihre readline Argument zurück: String readline (wahr); Und implementieren Sie eine Bedingung, um Registerkarten zu erkennen.

Verwandte Themen