.net - Hoe kan ik een groot tekstbestand regel voor regel lezen met Java?
Hoe kan ik een groot tekstbestand regel voor regel lezen met Java?
Ik moet een groot tekstbestand van ongeveer 5-6 GB regel voor regel lezen met Java.
Hoe kan ik dit snel doen?
Een veelvoorkomend patroon is om te gebruiken
U kunt de gegevens sneller lezen als u ervan uitgaat dat er geen tekencodering is. bijv. ASCII-7, maar het zal niet veel verschil maken. Het is zeer waarschijnlijk dat wat u met de gegevens doet veel langer zal duren.
EDIT: een minder gebruikelijk patroon om te voorkomen dat de reikwijdte van linelekt.
UPDATE: in Java 8 kunt u dat doen
OPMERKING: je moet de stream in een try-with- resource-blok om ervoor te zorgen dat de #close-methode erop wordt aangeroepen, anders wordt de onderliggende bestandshandle nooit gesloten totdat GC dit veel later doet.
Bekijk deze blog:
Java-bestand regel voor regel lezen – Java Zelfstudie
De buffergrootte kan worden opgegeven, of
de standaardgrootte kan worden gebruikt. De
standaard is groot genoeg voor de meeste
Zodra Java 8 uit is (maart 2014), kun je streams gebruiken:
Alle regels in het bestand afdrukken:
Hier is een voorbeeld met volledige foutafhandeling en ondersteunende karaktersetspecificatie voor pre-Java 7. Met Java 7 kunt u de syntaxis proberen-met-resources gebruiken, waardoor de code schoner wordt.
Als u alleen de standaardtekenset wilt, kunt u de InputStream overslaan en FileReader gebruiken.
Hier is de Groovy-versie, met volledige foutafhandeling:
Ik heb 10 verschillende manieren gedocumenteerd en getest om een ​​bestand in Java te lezenen heb ze vervolgens tegen elkaar uitgevoerd door waardoor ze testbestanden van 1KB tot 1GB inlezen. Dit zijn de 3 snelste bestandsleesmethoden voor het lezen van een testbestand van 1 GB.
Houd er rekening mee dat ik bij het uitvoeren van de prestatietests niets naar de console uitvoerde, omdat dat de test echt zou vertragen. Ik wilde alleen de onbewerkte leessnelheid testen.
Getest in Java 7, 8, 9. Dit was over het algemeen de snelste methode. Het lezen van een bestand van 1 GB duurde altijd iets minder dan 1 seconde.
Dit is met succes getest in Java 8 en 9, maar het zal niet werken in Java 7 vanwege het gebrek aan ondersteuning voor lambda-expressies. Het duurde ongeveer 3,5 seconden om een ​​bestand van 1 GB in te lezen, waardoor het op de tweede plaats kwam wat betreft het lezen van grotere bestanden.
Getest om te werken in Java 7, 8, 9. Dit duurde ongeveer 4,5 seconden om een ​​testbestand van 1 GB in te lezen.
Je kunt hierde volledige ranglijst voor alle 10 bestandsleesmethoden vinden.
In Java 8 zou je het volgende kunnen doen:
Enkele opmerkingen: de stream die wordt geretourneerd door Files.lines(in tegenstelling tot de meeste streams) moet worden gesloten. Om de redenen hier genoemdvermijd ik het gebruik van forEach(). De vreemde code (Iterable<String>) lines::iteratorwerpt een Stream naar een Iterable.
Wat u kunt doen, is de volledige tekst scannen met Scanner en regel voor regel door de tekst gaan.
Natuurlijk moet u het volgende importeren:
Scanner scant in principe alle tekst. De while-lus wordt gebruikt om door de hele tekst te lopen.
De functie .hasNextLine()is een boolean die true retourneert als er nog meer regels in de tekst staan. De functie .nextLine()geeft je een hele regel als String die je vervolgens kunt gebruiken zoals jij dat wilt. Probeer System.out.println(line)om de tekst af te drukken.
Noot: .txt is de tekst van het bestandstype.
FileReader laat je de codering niet specificeren, gebruik in plaats daarvan InputStreamReaderals je het moet specificeren:
Als u dit bestand uit Windows hebt geïmporteerd, heeft het mogelijk ANSI-codering (Cp1252), dus u moet de codering opgeven.
In Java 8 is er ook een alternatief voor het gebruik van Files.lines(). Als uw invoerbron geen bestand is, maar iets abstracters, zoals een Readerof een InputStream, kunt u de regels streamenvia de BufferedReaders lines()methode.
roept processLine()aan voor elke invoerregel die wordt gelezen door de BufferedReader.
U kunt Scannerklasse gebruiken
Voor het lezen van een bestandmet Java 8
Je moet de readLine()methode gebruiken in class BufferedReader.
Maak een nieuw object van die klasse en gebruik deze methode op hem en sla het op in een string.
De duidelijke manier om dit te bereiken,
Als u dataFile.txtin uw huidige directory heeft
De uitvoer zoals hieronder,
Het werkt voor mij. Ik hoop dat het jou ook zal helpen.
Je kunt streams gebruiken om het nauwkeuriger te doen:
Ik doe de leesroutine meestal rechttoe rechtaan:
Door het org.apache.commons.iopakket te gebruiken, leverde het meer prestaties, vooral in oude code die Java 6 en lager gebruikt.