Java - Schrijf naar bestand

1. Overzicht

In deze tutorial we zullen verschillende manieren onderzoeken om met Java naar een bestand te schrijven. We zullen er gebruik van maken BufferedWriter, PrintWriter, FileOutputStream, DataOutputStream, RandomAccessFile, FileChannel, en de Java 7 Bestanden hulpprogramma klasse.

We zullen ook kijken naar het vergrendelen van het bestand tijdens het schrijven en bespreken enkele laatste opmerkingen over het schrijven naar een bestand.

Deze tutorial maakt deel uit van de Java "Back to Basics" -serie hier op Baeldung.

2. Schrijf met BufferedWriter

Laten we eenvoudig beginnen en gebruiken BufferedWriter om een Draad naar een nieuw bestand:

public void whenWriteStringUsingBufferedWritter_thenCorrect () gooit IOException {String str = "Hallo"; BufferedWriter-schrijver = nieuwe BufferedWriter (nieuwe FileWriter (bestandsnaam)); schrijver.write (str); schrijver.close (); }

De output in het bestand zal zijn:

Hallo

We kunnen dan voeg een Draad naar het bestaande bestand:

@Test openbare leegte whenAppendStringUsingBufferedWritter_thenOldContentShouldExistToo () gooit IOException {String str = "World"; BufferedWriter-schrijver = nieuwe BufferedWriter (nieuwe FileWriter (bestandsnaam, waar)); writer.append (''); writer.append (str); schrijver.close (); }

Het bestand wordt dan:

Hallo Wereld

3. Schrijf met PrintWriter

Laten we vervolgens kijken hoe we kunnen gebruiken PrintWriter om opgemaakte tekst naar een bestand te schrijven:

@Test openbare ongeldige gegevenWritingStringToFile_whenUsingPrintWriter_thenCorrect () gooit IOException {FileWriter fileWriter = nieuwe FileWriter (bestandsnaam); PrintWriter printWriter = nieuwe PrintWriter (fileWriter); printWriter.print ("Some String"); printWriter.printf ("Productnaam is% s en de prijs is% d $", "iPhone", 1000); printWriter.close (); }

Het resulterende bestand bevat:

Een of andere String-productnaam is iPhone en de prijs is $ 1000

Merk op dat we niet alleen een raw schrijven Draad naar een bestand, maar ook een opgemaakte tekst met de printf methode.

We kunnen de schrijver maken met FileWriter, BufferedWriter, of zelfs System.out.

4. Schrijf met FileOutputStream

Laten we nu kijken hoe we het kunnen gebruiken FileOutputStream naar schrijf binaire gegevens naar een bestand.

De volgende code converteert een Draad in bytes en schrijft de bytes naar een bestand met FileOutputStream:

@Test openbare leegte gegevenWritingStringToFile_whenUsingFileOutputStream_thenCorrect () gooit IOException {String str = "Hallo"; FileOutputStream outputStream = nieuwe FileOutputStream (bestandsnaam); byte [] strToBytes = str.getBytes (); outputStream.write (strToBytes); outputStream.close (); }

De output in het bestand zal natuurlijk zijn:

Hallo

5. Schrijf met DataOutputStream

Laten we vervolgens eens kijken hoe we het kunnen gebruiken DataOutputStream om een Draad naar een bestand:

@Test openbare ongeldig gegevenWritingToFile_whenUsingDataOutputStream_thenCorrect () gooit IOException {String value = "Hallo"; FileOutputStream fos = nieuwe FileOutputStream (bestandsnaam); DataOutputStream outStream = nieuwe DataOutputStream (nieuwe BufferedOutputStream (fos)); outStream.writeUTF (waarde); outStream.close (); // controleer de resultaten String resultaat; FileInputStream fis = nieuwe FileInputStream (bestandsnaam); DataInputStream-lezer = nieuwe DataInputStream (fis); resultaat = reader.readUTF (); reader.close (); assertEquals (waarde, resultaat); }

6. Schrijf met RandomAccessFile

Laten we nu illustreren hoe schrijven en bewerken in een bestaand bestand in plaats van alleen naar een volledig nieuw bestand te schrijven of toe te voegen aan een bestaand bestand. Simpel gezegd: we hebben willekeurige toegang nodig.

RandomAccessFile stelt ons in staat om op een specifieke positie in het bestand te schrijven, gegeven de offset - vanaf het begin van het bestand - in bytes.

Deze code schrijft een geheel getal met een offset vanaf het begin van het bestand:

private void writeToPosition (String filename, int data, long position) gooit IOException {RandomAccessFile writer = new RandomAccessFile (filename, "rw"); writer.seek (positie); writer.writeInt (gegevens); schrijver.close (); }

Als we willen Lees de int opgeslagen op een specifieke locatiekunnen we deze methode gebruiken:

private int readFromPosition (String bestandsnaam, lange positie) gooit IOException {int resultaat = 0; RandomAccessFile reader = nieuwe RandomAccessFile (bestandsnaam, "r"); reader.seek (positie); resultaat = reader.readInt (); reader.close (); resultaat teruggeven; }

Laten we, om onze functies te testen, een geheel getal schrijven, het bewerken en het uiteindelijk teruglezen:

@Test openbare leegte whenWritingToSpecificPositionInFile_thenCorrect () gooit IOException {int data1 = 2014; int data2 = 1500; writeToPosition (bestandsnaam, data1, 4); assertEquals (data1, readFromPosition (bestandsnaam, 4)); writeToPosition (bestandsnaam2, data2, 4); assertEquals (data2, readFromPosition (bestandsnaam, 4)); }

7. Schrijf met FileChannel

Als we te maken hebben met grote bestanden, FileChannel kan sneller zijn dan standaard IO. De volgende code schrijft Draad naar een bestand met FileChannel:

@Test openbare ongeldig gegevenWritingToFile_whenUsingFileChannel_thenCorrect () gooit IOException {RandomAccessFile stream = nieuwe RandomAccessFile (bestandsnaam, "rw"); FileChannel-kanaal = stream.getChannel (); String value = "Hallo"; byte [] strBytes = waarde.getBytes (); ByteBuffer-buffer = ByteBuffer.allocate (strBytes.length); buffer.put (strBytes); buffer.flip (); channel.write (buffer); stream.close (); kanaal.close (); // controleer RandomAccessFile reader = nieuwe RandomAccessFile (bestandsnaam, "r"); assertEquals (waarde, reader.readLine ()); reader.close (); }

8. Schrijf met Bestanden Klasse

Java 7 introduceert een nieuwe manier van werken met het bestandssysteem, samen met een nieuwe utility class: Bestanden.

De ... gebruiken Bestanden class, kunnen we bestanden en mappen maken, verplaatsen, kopiëren en verwijderen. Het kan ook worden gebruikt om een ​​bestand te lezen en ernaar te schrijven:

@Test openbare leegte gegevenUsingJava7_whenWritingToFile_thenCorrect () gooit IOException {String str = "Hallo"; Padpad = Paths.get (bestandsnaam); byte [] strToBytes = str.getBytes (); Files.write (pad, strToBytes); String read = Files.readAllLines (pad) .get (0); assertEquals (str, lezen); }

9. Schrijf naar een tijdelijk bestand

Laten we nu proberen naar een tijdelijk bestand te schrijven. De volgende code maakt een tijdelijk bestand en schrijft een Draad naar het:

@Test public void whenWriteToTmpFile_thenCorrect () gooit IOException {String toWrite = "Hallo"; Bestand tmpFile = File.createTempFile ("test", ".tmp"); FileWriter-schrijver = nieuwe FileWriter (tmpFile); writer.write (toWrite); schrijver.close (); BufferedReader-lezer = nieuwe BufferedReader (nieuwe FileReader (tmpFile)); assertEquals (toWrite, reader.readLine ()); reader.close (); }

Zoals we kunnen zien, is het alleen het maken van het tijdelijke bestand dat interessant en anders is. Na dat punt is schrijven naar het bestand hetzelfde.

10. Vergrendel bestand alvorens te schrijven

Ten slotte, wanneer we naar een bestand schrijven, moeten we er soms extra voor zorgen dat niemand anders tegelijkertijd naar dat bestand schrijft. In principe moeten we dat bestand tijdens het schrijven kunnen vergrendelen.

Laten we er gebruik van maken FileChannel om te proberen het bestand te vergrendelen voordat u ernaar schrijft:

@Test openbare leegte whenTryToLockFile_thenItShouldBeLocked () gooit IOException {RandomAccessFile stream = nieuwe RandomAccessFile (bestandsnaam, "rw"); FileChannel-kanaal = stream.getChannel (); FileLock-vergrendeling = null; probeer {lock = channel.tryLock (); } catch (final OverlappingFileLockException e) {stream.close (); kanaal.close (); } stream.writeChars ("testvergrendeling"); lock.release (); stream.close (); kanaal.close (); }

Merk op dat als het bestand al is vergrendeld wanneer we proberen de vergrendeling te verkrijgen, een OverlappingFileLockException zal worden gegooid.

11. Opmerkingen

Laten we, nadat we zoveel methoden hebben onderzocht om naar een bestand te schrijven, enkele belangrijke opmerkingen bespreken:

  • Als we proberen te lezen uit een bestand dat niet bestaat, wordt een FileNotFoundException zal worden gegooid.
  • Als we proberen te schrijven naar een bestand dat niet bestaat, wordt het bestand eerst gemaakt en wordt er geen uitzondering gegenereerd.
  • Het is erg belangrijk om de stream na gebruik te sluiten, aangezien deze niet impliciet is gesloten, om alle bijbehorende bronnen vrij te geven.
  • In de outputstroom is het dichtbij() methode aanroepen doorspoelen () voordat de bronnen worden vrijgegeven, wat ervoor zorgt dat gebufferde bytes naar de stream worden geschreven.

Als we naar de gangbare gebruikspraktijken kijken, kunnen we dat bijvoorbeeld zien PrintWriter wordt gebruikt om opgemaakte tekst te schrijven, FileOutputStream om binaire gegevens te schrijven, DataOutputStream om primitieve datatypes te schrijven, RandomAccessFile om naar een specifieke positie te schrijven, en FileChannel om sneller te schrijven in grotere bestanden. Sommige van de API's van deze klassen staan ​​meer toe, maar dit is een goede plek om te beginnen.

12. Conclusie

Dit artikel illustreert de vele opties om gegevens met Java naar een bestand te schrijven.

De implementatie van al deze voorbeelden en codefragmenten is te vinden op GitHub.


$config[zx-auto] not found$config[zx-overlay] not found