Overzicht
In deze tutorial zullen we verschillende manieren verkennen om te lezen vanuit een bestand in Java .
Ten eerste zullen we leren hoe we een bestand kunnen laden vanuit het klassenpad, een URL of vanuit een JAR-bestand met behulp van standaard Java-klassen.
Ten tweede zullen we zien hoe om de inhoud te lezen met BufferedReader, Scanner, StreamTokenizer, DataInputStream, SequenceInputStream en FileChannel. We zullen ook bespreken hoe je een UTF-8-gecodeerd bestand kunt lezen.
Ten slotte zullen we de nieuwe technieken onderzoeken om te laden en lees een bestand in Java 7 en Java 8.
Dit artikel maakt deel uit van de “Java – Back to Basic” -serie op Baeldung.
Verder lezen:
Java – Maak een bestand
Java – Schrijf naar bestand
Setup
2.1 Invoerbestand
In de meeste voorbeelden in dit artikel lezen we een tekstbestand met de bestandsnaam fileTest.txt dat één regel bevat:
Voor een paar voorbeelden gebruiken we een ander bestand; in deze gevallen zullen we het bestand en de inhoud expliciet vermelden.
2.2 Helper-methode
We gebruiken een reeks testvoorbeelden met kern Alleen Java-klassen, en in de tests zullen we beweringen gebruiken met Hamcrest-matchers.
Tests zullen een gemeenschappelijke readFromInputStream-methode delen die een InputStream omzet in String om de resultaten gemakkelijker te bevestigen:
Merk op dat er andere manieren zijn om hetzelfde resultaat te bereiken. We kunnen dit artikel raadplegen voor enkele alternatieven.
Een bestand lezen van het klassenpad
3.1 . Standaard Java gebruiken
In dit gedeelte wordt uitgelegd hoe u een bestand kunt lezen dat beschikbaar is op een klassenpad. We “zullen de” fileTest.txt “lezen die beschikbaar is onder src / main / resources :
In het bovenstaande codefragment hebben we de huidige klasse gebruikt om een bestand te laden met de methode getResourceAsStream en hebben we het absolute pad van het te laden bestand doorgegeven.
Dezelfde methode is beschikbaar op ook een ClassLoader-instantie:
We verkrijgen de classLoa van de huidige klasse met behulp van getClass (). getClassLoader ().
Het belangrijkste verschil is dat wanneer de getResourceAsStream op een ClassLoader-instantie wordt gebruikt, het pad als absoluut wordt beschouwd, beginnend vanaf de root van het klassenpad.
Bij gebruik tegen een Class-instantie kan het pad relatief zijn ten opzichte van het pakket, of een absoluut pad, dat wordt aangegeven door de voorlopende schuine streep.
Merk natuurlijk op dat in de praktijk moeten open streams altijd gesloten zijn, zoals de InputStream in ons voorbeeld:
3.2. De commons-io-bibliotheek gebruiken
Een andere veel voorkomende optie is het gebruik van de FileUtils-klasse van het commons-io-pakket:
Hier geven we het File-object door aan de methode readFileToString () van de klasse FileUtils. Deze utility-klasse slaagt erin de inhoud te laden zonder de noodzaak om standaardcode te schrijven om een InputStream-instantie te maken en gegevens te lezen.
Dezelfde bibliotheek biedt ook de IOUtils-klasse:
Hier hebben we geef het FileInputStream-object door aan de methode toString () van de IOUtils-klasse. Deze utility class werkt op dezelfde manier als de vorige om een InputStream-instantie te maken en gegevens te lezen.
Lezen met BufferedReader
Laten we nu ” s richten zich op verschillende manieren om de inhoud van een bestand te ontleden.
We beginnen met een eenvoudige manier om uit een bestand te lezen met BufferedReader:
Merk op dat readLine () zal terugkeren null wanneer het einde van het bestand is bereikt.
Lezen uit een bestand met Java NIO
In JDK7 is het NIO-pakket aanzienlijk bijgewerkt.
Laten we een voorbeeld bekijken met de klasse Files en de readAllLines-methode. De readAllLines-methode accepteert een pad.
Padklasse kan worden beschouwd als een upgrade van de java.io.File met enkele aanvullende bewerkingen.
5.1. Een klein bestand lezen
De volgende code laat zien hoe je een klein bestand kunt lezen met de nieuwe klasse Files:
Merk op dat we de readAllBytes () methode ook als we binaire gegevens nodig hebben.
5.2. Een groot bestand lezen
Als we een groot bestand met de klasse Files willen lezen, kunnen we de BufferedReader gebruiken.
De volgende code leest het bestand met de nieuwe klasse Files en BufferedReader:
5.3. Een bestand lezen met Files.lines ()
JDK8 biedt de methode lines () binnen de klasse Files. Het retourneert een stroom van stringelementen.
Laten we eens kijken naar een voorbeeld van hoe gegevens in bytes kunnen worden gelezen en gedecodeerd met UTF-8-tekenset.
De volgende code leest het bestand met de nieuwe Files.lines ():
Als we Stream gebruiken met IO-kanalen zoals bestandsbewerkingen, moeten we de stream expliciet sluiten met de methode close ().
Zoals we kunnen zien, biedt de Files API een andere gemakkelijke manier om de bestandsinhoud in een string te lezen.
In de volgende secties zullen we kijken naar andere, minder gebruikelijke methoden om het lezen van een bestand dat in sommige situaties geschikt zou kunnen zijn.
Lezen met scanner
Laten we vervolgens een scanner gebruiken om uit het bestand te lezen. Hier gebruiken we witruimte als scheidingsteken:
Merk op dat het standaard scheidingsteken de witruimte is, maar er kunnen meerdere scheidingstekens worden gebruikt met een scanner.
De klasse Scanner is handig bij het lezen inhoud van de console, of wanneer de inhoud primitieve waarden bevat, met een bekend scheidingsteken (bijvoorbeeld: een lijst met gehele getallen gescheiden door een spatie).
Lezen met StreamTokenizer
Laten we nu een tekstbestand in tokens lezen met behulp van een StreamTokenizer.
De tokenizer werkt door eerst uit te zoeken wat het volgende token is, String of getal. We doen dat door naar het veld tokenizer.ttype te kijken.
Vervolgens lezen we het daadwerkelijke token op basis van dit type:
- tokenizer.nval – als het type was een getal
- tokenizer.sval – als het type een tekenreeks was
In dit voorbeeld gebruiken we een ander invoerbestand dat eenvoudig bevat:
De volgende code leest zowel de String als het nummer uit het bestand:
Merk op hoe het einde van bestandstoken aan het einde wordt gebruikt.
Deze benadering is handig voor het parseren van een invoerstroom in tokens.
Lezen met DataInputStream
We kunnen DataInputStream gebruiken om binaire of primitieve gegevenstypen uit een bestand.
De volgende test leest het bestand met behulp van een DataInputStream:
Lezen met FileChannel
Als we een groot bestand lezen, FileChannel kan sneller zijn dan standaard IO.
De volgende code leest gegevensbytes uit het bestand met behulp van FileChannel en RandomAccessFile:
Een UTF-8-codering lezen ed Bestand
Laten we nu eens kijken hoe we een UTF-8 gecodeerd bestand kunnen lezen met BufferedReader. In dit voorbeeld lezen we een bestand dat Chinese karakters bevat:
Inhoud lezen van URL
Om inhoud van een URL te lezen, gebruiken we “/” URL in ons voorbeeld:
Er zijn ook alternatieve manieren om verbinding te maken met een URL. Hier hebben we de URL en URLConnection-klasse gebruikt die beschikbaar is in de standaard SDK.
Een bestand lezen uit een JAR
Om een bestand te lezen dat zich in een JAR-bestand, hebben we een JAR nodig met een bestand erin. Voor ons voorbeeld zullen we “LICENSE.txt” lezen uit het “hamcrest-library-1.3.jar” bestand:
Hier willen we LICENSE.txt laden dat zich in de Hamcrest-bibliotheek bevindt, dus we zullen gebruiken de Matcher-klasse die helpt om een bron te krijgen. Hetzelfde bestand kan ook worden geladen met de classloader.
Conclusie
Zoals we kunnen zien, er zijn veel mogelijkheden om een bestand te laden en er gegevens uit te lezen met gewone Java.
We kunnen een bestand laden vanaf verschillende locaties, zoals klassenpad, URL of jar-bestanden.
Vervolgens kan BufferedReader gebruiken om regel voor regel te lezen, Scanner om te lezen met verschillende scheidingstekens, StreamTokenizer om een bestand in tokens te lezen, DataInputStream om binaire gegevens en primitieve gegevenstypen te lezen, SequenceInput Stream om meerdere bestanden in één stroom te linken, FileChannel om sneller van grote te lezen bestanden, enz.