Derzeit verwende ich Scanner/Dateileiter und verwende whilenextline. Ich denke, dass diese Methode nicht sehr effizient ist. Gibt es eine andere Methode, um Dateien mit ähnlichen Funktionen zu lesen?
public void Read(String file) {
Scanner sc = null;
try {
sc = new Scanner(new FileReader(file));
while (sc.hasNextLine()) {
String text = sc.nextLine();
String[] file_Array = text.split(" ", 3);
if (file_Array[0].equalsIgnoreCase("case")) {
//do something
} else if (file_Array[0].equalsIgnoreCase("object")) {
//do something
} else if (file_Array[0].equalsIgnoreCase("classes")) {
//do something
} else if (file_Array[0].equalsIgnoreCase("function")) {
//do something
}
else if (file_Array[0].equalsIgnoreCase("ignore")) {
//do something
}
else if (file_Array[0].equalsIgnoreCase("display")) {
//do something
}
}
} catch (FileNotFoundException e) {
System.out.println("Input file " + file + " not found");
System.exit(1);
} finally {
sc.close();
}
}
Sie werden feststellen, dass BufferedReader.readLine()
so schnell ist, wie Sie es brauchen: Sie können Millionen von Zeilen pro Sekunde lesen. Es ist wahrscheinlicher, dass die Aufteilung und Verarbeitung von Strings die Performance-Probleme verursacht, auf die Sie stoßen.
Scanner
kann nicht so schnell wie BufferedReader
sein, da zum Lesen von Textdateien reguläre Ausdrücke verwendet werden, was sie im Vergleich zu BufferedReader
langsamer macht. Mit BufferedReader
können Sie einen Block aus einer Textdatei lesen.
BufferedReader bf = new BufferedReader(new FileReader("FileName"));
als nächstes können Sie readLine () verwenden, um von bf zu lesen.
Hoffe, es dient deinem Zweck.
sie können FileChannel und ByteBuffer von Java NIO verwenden. Die ByteBuffer-Größe ist der kritischste Teil beim Lesen von Daten, was ich beobachtet habe. Der folgende Code liest den Inhalt der Datei.
static public void main( String args[] ) throws Exception
{
FileInputStream fileInputStream = new FileInputStream(
new File("sample4.txt"));
FileChannel fileChannel = fileInputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
fileChannel.read(byteBuffer);
byteBuffer.flip();
int limit = byteBuffer.limit();
while(limit>0)
{
System.out.print((char)byteBuffer.get());
limit--;
}
fileChannel.close();
}
Sie können hier nach '\ n' nach neuer Zeile suchen. Vielen Dank.
Sogar Sie können mit dem Scatter- und Getter-Verfahren Dateien schneller lesen, d. H.
fileChannel.get(buffers);
woher
ByteBuffer b1 = ByteBuffer.allocate(B1);
ByteBuffer b2 = ByteBuffer.allocate(B2);
ByteBuffer b3 = ByteBuffer.allocate(B3);
ByteBuffer[] buffers = {b1, b2, b3};
Dies erspart dem Benutzerprozess, mehrere Systemaufrufe durchzuführen (was sehr teuer sein kann), und ermöglicht dem Kernel, die Handhabung der Daten zu optimieren, da er Informationen über die Gesamtübertragung enthält. Wenn mehrere CPUs verfügbar sind, können sogar mehrere Puffer gefüllt und entleert werden gleichzeitig.
Von dieses Buch.
Ich habe einen Gist Vergleich verschiedener Methoden gemacht:
import Java.io.*;
import Java.nio.file.Files;
import Java.nio.file.Paths;
import Java.util.ArrayList;
import Java.util.LinkedList;
import Java.util.List;
import Java.util.Scanner;
import Java.util.function.Function;
public class Main {
public static void main(String[] args) {
String path = "resources/testfile.txt";
measureTime("BufferedReader.readLine() into ArrayList", Main::bufferReaderToLinkedList, path);
measureTime("BufferedReader.readLine() into LinkedList", Main::bufferReaderToArrayList, path);
measureTime("Files.readAllLines()", Main::readAllLines, path);
measureTime("Scanner.nextLine() into ArrayList", Main::scannerArrayList, path);
measureTime("Scanner.nextLine() into LinkedList", Main::scannerLinkedList, path);
measureTime("RandomAccessFile.readLine() into ArrayList", Main::randomAccessFileArrayList, path);
measureTime("RandomAccessFile.readLine() into LinkedList", Main::randomAccessFileLinkedList, path);
System.out.println("-----------------------------------------------------------");
}
private static void measureTime(String name, Function<String, List<String>> fn, String path) {
System.out.println("-----------------------------------------------------------");
System.out.println("run: " + name);
long startTime = System.nanoTime();
List<String> l = fn.apply(path);
long estimatedTime = System.nanoTime() - startTime;
System.out.println("lines: " + l.size());
System.out.println("estimatedTime: " + estimatedTime / 1_000_000_000.);
}
private static List<String> bufferReaderToLinkedList(String path) {
return bufferReaderToList(path, new LinkedList<>());
}
private static List<String> bufferReaderToArrayList(String path) {
return bufferReaderToList(path, new ArrayList<>());
}
private static List<String> bufferReaderToList(String path, List<String> list) {
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(
path));
String line = reader.readLine();
while (line != null) {
line = reader.readLine();
list.add(line);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
private static List<String> readAllLines(String path) {
try {
return Files.readAllLines(Paths.get(path));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static List<String> randomAccessFileLinkedList(String path) {
return randomAccessFile(path, new LinkedList<>());
}
private static List<String> randomAccessFileArrayList(String path) {
return randomAccessFile(path, new ArrayList<>());
}
private static List<String> randomAccessFile(String path, List<String> list) {
try {
RandomAccessFile file = new RandomAccessFile(path, "r");
String str;
while ((str = file.readLine()) != null) {
list.add(str);
}
file.close();
} catch (IOException e) {
e.printStackTrace();
}
return list;
}
private static List<String> scannerLinkedList(String path) {
return scanner(path, new LinkedList<>());
}
private static List<String> scannerArrayList(String path) {
return scanner(path, new ArrayList<>());
}
private static List<String> scanner(String path, List<String> list) {
try {
Scanner scanner = new Scanner(new File(path));
while (scanner.hasNextLine()) {
list.add(scanner.nextLine());
}
scanner.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return list;
}
}
führen Sie: BufferedReader.readLine () in ArrayList aus Zeilen: 1000000, geschätzteZeit: 0,105118655
führen Sie: BufferedReader.readLine () in LinkedList aus Zeilen: 1000000, geschätzteZeit: 0,072696934
run: Files.readAllLines (), Zeilen: 1000000, geschätzte Zeit: 0,087753316
führen Sie: Scanner.nextLine () in ArrayList aus Zeilen: 1000000, geschätzte Zeit: 0,743121734
führen Sie: Scanner.nextLine () in LinkedList aus Zeilen: 1000000, geschätzteZeit: 0,867049885
run: RandomAccessFile.readLine () in ArrayList Zeilen: 1000000, geschätzteZeit: 11.413323046
run: RandomAccessFile.readLine () in LinkedList Zeilen: 1000000, geschätzteZeit: 11.423862897
BufferedReader
ist die schnellste, Files.readAllLines()
ist auch akzeptabel, Scanner
ist aufgrund von regex langsam, RandomAccessFile
ist inakzeptabel
Verwenden Sie BufferedReader für den Dateizugriff mit hoher Leistung. Die Standardpuffergröße von 8192 Bytes ist jedoch oft zu klein. Bei großen Dateien können Sie die Puffergröße erhöhen um Größenordnungen erhöhen, um die Leseleistung von Dateien zu verbessern. Zum Beispiel:
BufferedReader br = new BufferedReader("file.dat", 1000 * 8192);
while ((thisLine = br.readLine()) != null) {
System.out.println(thisLine);
}
wir aktualisieren gerade diesen Thread. Jetzt haben wir Java 8, um diesen Job zu erledigen:
List<String> lines = Files.readAllLines(Paths.get(file_path);
Sie müssen untersuchen, welcher Teil des Programms Zeit braucht.
Als Antwort von EJP sollten Sie BufferedReader verwenden.
Wenn die Zeichenfolgenverarbeitung wirklich Zeit in Anspruch nimmt, sollten Sie die Verwendung von Threads in Betracht ziehen. Ein Thread liest die Zeilen aus Datei und Warteschlangen. Andere String-Prozessor-Threads werden Zeilen aus der Warteschlange entfernen und sie verarbeiten. Sie müssen untersuchen, wie viele Threads verwendet werden sollen. Die Anzahl der Threads, die Sie in der Anwendung verwenden sollten, muss mit der Anzahl der Kerne in der CPU in Beziehung gesetzt werden. In diesem Fall wird die volle CPU verwendet.