2016-04-14 20 views
-1

Derzeit, um die gewünschte Zeile aus der Datei zu finden, lese ich die Datei Zeile für Zeile, bis die Zeichenfolge, die ich suche, der aktuellen Zeile entspricht.Ergreifen Sie eine Zeichenfolge aus einer Datei in einer Zeile?

Dies ist wie eine schlechte Programmierpraxis, da meine Dateien 1000+ Zeilen sind; Gibt es eine Möglichkeit, entweder einem Scanner oder einem gepufferten Lesegerät (oder etwas anderem?) zu sagen, eine Zeichenkette aus Zeichen AT einer gegebenen Zeile zu erstellen?

EDIT: es scheint, dass dies nicht physikalisch möglich ist, wie ajb darauf hingewiesen.

Ich denke, die beste Lösung wäre, die gesamte Datei in einen String [] von Zeilen zu lesen.

+2

Ich sehe wirklich keinen Weg um potenziell die gesamte Datei zu scannen, um zu finden, was Sie wollen. –

+0

Benchmark die Leistung in Editoren wie Notepad ++ und Sie werden eine Verzögerung für eine Datei mit 100K + Zeilen sehen. –

+3

Sofern Sie sich nicht auf einem VMS-System befinden (falls noch weitere vorhanden sind), werden Textdateien als Zeichenfolgen mit '\ n' oder' \ r \ n' zwischen jeder Zeile gespeichert. Es gibt keinen "Index" oder irgendetwas, um dem System zu sagen, wo der Anfang jeder Zeile ist, oder irgendwelche anderen Metadaten, die helfen würden, dies zu beschleunigen. Es ist ungefähr so, als würde ich dir ein Buch geben und sagen "Finde das 1000ste" im Buch ". Es gibt keine Möglichkeit, es zu tun, außer sie alle zu zählen, angefangen von Anfang an. – ajb

Antwort

0

Ja, Sie können einen Offset einstellen, bei dem das Lesen oder Schreiben der Datei erfolgt. Verwenden Sie die RandomAccessFile-API für dasselbe. Einschließlich eines Beispielcodes unten.

import java.io.*; 

public class RandomAccessFileDemo { 

    public static void main(String[] args) { 
     try { 
     // create a new RandomAccessFile with filename test 
     RandomAccessFile raf = new RandomAccessFile("F:/test.txt", "r"); 

     System.out.println("Output without setting offset, i.e. from start of file"); 
     // print the lines 
     String temp=""; 
     while((temp = raf.readLine()) != null) 
      System.out.println(temp); 

      System.out.println(); 
     // set the file pointer at 20 position 
     raf.seek(20); 
      System.out.println("Output using seek and setting offset to 20"); 
     // print the line 
     while((temp = raf.readLine()) != null) 
      System.out.println(temp); 

     } catch (IOException ex) { 
     ex.printStackTrace(); 
     } 
    } 
} 

Dies wird test.txt meine Probe

This is an example 
Hello World 
Trying RandomAccessFile 

in F-Laufwerk platziert Und dies ist die Ausgabe des Programms

Output without setting offset, i.e. from start of file 
This is an example 
Hello World 
Trying RandomAccessFile 

Output using seek and setting offset to 20 
Hello World 
Trying RandomAccessFile 
+0

Wie hilft das, die _n_'te Zeile zu finden? – ajb

+0

@ajb Es tut es nicht. Die Anforderung in der Frage war, nach bestimmten Zeichen zu lesen –

+0

Nein, Sie haben die Frage falsch verstanden. – ajb

0

Versuchen, da die Anzahl mutli-Threading-Konzept unter Verwendung von Zeile/Zeilen in Ihrer Datei sind mehr.

private void multiThreadRead(int num){ 

    for(int i=1; i<= num; i++) { 
     new Thread(readIndivColumn(i),""+i).start(); 
    } 
} 

private Runnable readIndivColumn(final int colNum){ 
    return new Runnable(){ 
     @Override 
     public void run() { 
      // TODO Auto-generated method stub 
      try { 

       long startTime = System.currentTimeMillis(); 
       System.out.println("From Thread no:"+colNum+" Start time:"+startTime); 

       RandomAccessFile raf = new RandomAccessFile("./src/test/test1.csv","r"); 
       String line = ""; 
       //System.out.println("From Thread no:"+colNum); 

       while((line = raf.readLine()) != null){ 
        //System.out.println(line); 
        //System.out.println(StatUtils.getCellValue(line, colNum)); 
       } 


       long elapsedTime = System.currentTimeMillis() - startTime; 

       String formattedTime = String.format("%d min, %d sec", 
         TimeUnit.MILLISECONDS.toMinutes(elapsedTime), 
         TimeUnit.MILLISECONDS.toSeconds(elapsedTime) - 
         TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsedTime)) 
        ); 

       System.out.println("From Thread no:"+colNum+" Finished Time:"+formattedTime); 
      } 
      catch (Exception e) { 
       // TODO Auto-generated catch block 
       System.out.println("From Thread no:"+colNum +"===>"+e.getMessage()); 

       e.printStackTrace(); 
      } 
     } 
    }; 
} 

private void sequentialRead(int num){ 
    try{ 
     long startTime = System.currentTimeMillis(); 
     System.out.println("Start time:"+startTime); 

     for(int i =0; i < num; i++){ 
      RandomAccessFile raf = new RandomAccessFile("./src/test/test1.csv","r"); 
      String line = ""; 

      while((line = raf.readLine()) != null){ 
       //System.out.println(line); 
      }    
     } 

     long elapsedTime = System.currentTimeMillis() - startTime; 

     String formattedTime = String.format("%d min, %d sec", 
       TimeUnit.MILLISECONDS.toMinutes(elapsedTime), 
       TimeUnit.MILLISECONDS.toSeconds(elapsedTime) - 
       TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(elapsedTime)) 
      ); 

     System.out.println("Finished Time:"+formattedTime); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
     // TODO: handle exception 
    } 

} 
    public TesterClass() { 

    sequentialRead(1);  
    this.multiThreadRead(1); 

} 
0

Java NIO hat eine Menge neuer Methoden und einfache Möglichkeiten, genau das tun, was Sie wollen:

public List<String> getLinesInFile(File f){ 
    return Files.readAllLines(f.toPath()); 
} 

Oder man kann es als ein massiver String analysieren und danach suchen die enthält Methode:

Verwandte Themen