Java - In Datei schreiben

1. Übersicht

In diesem Tutorial werden verschiedene Möglichkeiten zum Schreiben in eine Datei mit Java untersucht. Wir nutzen BufferedWriter , Printwriter , Fileoutputstream , Dataoutputstream , Random , Filechannel, und die Java - 7 - Dateien Utility - Klasse.

Wir werden uns auch mit dem Sperren der Datei während des Schreibens befassen und einige abschließende Aspekte beim Schreiben in eine Datei besprechen.

Dieses Tutorial ist Teil der Java-Reihe „Back to Basics“ hier auf Baeldung.

2. Schreiben Sie mit BufferedWriter

Beginnen wir einfach und verwenden BufferedWriter , um einen String in eine neue Datei zu schreiben :

public void whenWriteStringUsingBufferedWritter_thenCorrect() throws IOException { String str = "Hello"; BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)); writer.write(str); writer.close(); }

Die Ausgabe in der Datei lautet:

Hello

Wir können dann einen String an die vorhandene Datei anhängen :

@Test public void whenAppendStringUsingBufferedWritter_thenOldContentShouldExistToo() throws IOException { String str = "World"; BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true)); writer.append(' '); writer.append(str); writer.close(); }

Die Datei lautet dann:

Hello World

3. Schreiben Sie mit PrintWriter

Als nächstes wollen wir sehen, wie wir PrintWriter verwenden können , um formatierten Text in eine Datei zu schreiben :

@Test public void givenWritingStringToFile_whenUsingPrintWriter_thenCorrect() throws IOException { FileWriter fileWriter = new FileWriter(fileName); PrintWriter printWriter = new PrintWriter(fileWriter); printWriter.print("Some String"); printWriter.printf("Product name is %s and its price is %d $", "iPhone", 1000); printWriter.close(); }

Die resultierende Datei enthält:

Some String Product name is iPhone and its price is 1000$

Beachten Sie, dass wir nicht nur einen rohen String in eine Datei schreiben , sondern auch formatierten Text mit der printf- Methode.

Wir können den Writer erstellen Filewriter , BufferedWriter oder sogar System.out .

4. Schreiben Sie mit FileOutputStream

Lassen Sie uns nun sehen, wie wir FileOutputStream verwenden können , um Binärdaten in eine Datei zu schreiben.

Der folgende Code konvertiert einen String in Bytes und schreibt die Bytes mit FileOutputStream in eine Datei :

@Test public void givenWritingStringToFile_whenUsingFileOutputStream_thenCorrect() throws IOException { String str = "Hello"; FileOutputStream outputStream = new FileOutputStream(fileName); byte[] strToBytes = str.getBytes(); outputStream.write(strToBytes); outputStream.close(); }

Die Ausgabe in der Datei ist natürlich:

Hello

5. Schreiben Sie mit DataOutputStream

Schauen wir uns als nächstes an, wie wir mit DataOutputStream einen String in eine Datei schreiben können :

@Test public void givenWritingToFile_whenUsingDataOutputStream_thenCorrect() throws IOException { String value = "Hello"; FileOutputStream fos = new FileOutputStream(fileName); DataOutputStream outStream = new DataOutputStream(new BufferedOutputStream(fos)); outStream.writeUTF(value); outStream.close(); // verify the results String result; FileInputStream fis = new FileInputStream(fileName); DataInputStream reader = new DataInputStream(fis); result = reader.readUTF(); reader.close(); assertEquals(value, result); }

6. Schreiben Sie mit RandomAccessFile

Lassen Sie uns nun veranschaulichen, wie Sie in eine vorhandene Datei schreiben und bearbeiten, anstatt nur in eine vollständig neue Datei zu schreiben oder an eine vorhandene anzuhängen. Einfach ausgedrückt: Wir brauchen wahlfreien Zugriff.

Mit RandomAccessFile können wir an einer bestimmten Position in der Datei schreiben, wobei der Versatz - vom Anfang der Datei - in Byte angegeben wird.

Dieser Code schreibt einen ganzzahligen Wert mit einem Offset vom Anfang der Datei:

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

Wenn wir das an einem bestimmten Ort gespeicherte int lesen möchten , können wir diese Methode verwenden:

private int readFromPosition(String filename, long position) throws IOException { int result = 0; RandomAccessFile reader = new RandomAccessFile(filename, "r"); reader.seek(position); result = reader.readInt(); reader.close(); return result; }

Um unsere Funktionen zu testen, schreiben wir eine Ganzzahl, bearbeiten sie und lesen sie schließlich zurück:

@Test public void whenWritingToSpecificPositionInFile_thenCorrect() throws IOException { int data1 = 2014; int data2 = 1500; writeToPosition(fileName, data1, 4); assertEquals(data1, readFromPosition(fileName, 4)); writeToPosition(fileName2, data2, 4); assertEquals(data2, readFromPosition(fileName, 4)); }

7. Schreiben Sie mit FileChannel

Wenn es sich um große Dateien handelt, kann FileChannel schneller als Standard- E / A sein. Der folgende Code schreibt mit FileChannel einen String in eine Datei :

@Test public void givenWritingToFile_whenUsingFileChannel_thenCorrect() throws IOException { RandomAccessFile stream = new RandomAccessFile(fileName, "rw"); FileChannel channel = stream.getChannel(); String value = "Hello"; byte[] strBytes = value.getBytes(); ByteBuffer buffer = ByteBuffer.allocate(strBytes.length); buffer.put(strBytes); buffer.flip(); channel.write(buffer); stream.close(); channel.close(); // verify RandomAccessFile reader = new RandomAccessFile(fileName, "r"); assertEquals(value, reader.readLine()); reader.close(); }

8. Schreiben Sie mit Dateien Klasse

Java 7 bietet eine neue Arbeitsweise mit dem Dateisystem sowie eine neue Dienstprogrammklasse: Dateien .

Mit der Files- Klasse können wir Dateien und Verzeichnisse erstellen, verschieben, kopieren und löschen. Es kann auch zum Lesen und Schreiben in eine Datei verwendet werden:

@Test public void givenUsingJava7_whenWritingToFile_thenCorrect() throws IOException { String str = "Hello"; Path path = Paths.get(fileName); byte[] strToBytes = str.getBytes(); Files.write(path, strToBytes); String read = Files.readAllLines(path).get(0); assertEquals(str, read); }

9. Schreiben Sie in eine temporäre Datei

Versuchen wir nun, in eine temporäre Datei zu schreiben. Der folgende Code erstellt eine temporäre Datei und schreibt einen String in diese:

@Test public void whenWriteToTmpFile_thenCorrect() throws IOException { String toWrite = "Hello"; File tmpFile = File.createTempFile("test", ".tmp"); FileWriter writer = new FileWriter(tmpFile); writer.write(toWrite); writer.close(); BufferedReader reader = new BufferedReader(new FileReader(tmpFile)); assertEquals(toWrite, reader.readLine()); reader.close(); }

Wie wir sehen können, ist nur die Erstellung der temporären Datei interessant und anders. Nach diesem Zeitpunkt ist das Schreiben in die Datei dasselbe.

10. Datei vor dem Schreiben sperren

Schließlich müssen wir beim Schreiben in eine Datei manchmal besonders sicherstellen, dass niemand anderes gleichzeitig in diese Datei schreibt. Grundsätzlich müssen wir in der Lage sein, diese Datei beim Schreiben zu sperren.

Let's make use of FileChannel to try locking the file before writing to it:

@Test public void whenTryToLockFile_thenItShouldBeLocked() throws IOException { RandomAccessFile stream = new RandomAccessFile(fileName, "rw"); FileChannel channel = stream.getChannel(); FileLock lock = null; try { lock = channel.tryLock(); } catch (final OverlappingFileLockException e) { stream.close(); channel.close(); } stream.writeChars("test lock"); lock.release(); stream.close(); channel.close(); }

Note that if the file is already locked when we try to acquire the lock, an OverlappingFileLockException will be thrown.

11. Notes

After exploring so many methods of writing to a file, let's discuss some important notes:

  • If we try to read from a file that doesn't exist, a FileNotFoundException will be thrown.
  • If we try to write to a file that doesn't exist, the file will be created first and no exception will be thrown.
  • It is very important to close the stream after using it, as it is not closed implicitly, to release any resources associated with it.
  • In output stream, the close() method calls flush() before releasing the resources, which forces any buffered bytes to be written to the stream.

Looking at the common usage practices, we can see, for example, that PrintWriter is used to write formatted text, FileOutputStream to write binary data, DataOutputStream to write primitive data types, RandomAccessFile to write to a specific position, and FileChannel to write faster in larger files. Some of the APIs of these classes do allow more, but this is a good place to start.

12. Conclusion

This article illustrated the many options of writing data to a file using Java.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie auf GitHub.