Java - In Datei schreiben

Java - In Datei schreiben

1. Überblick

In diesem Tutorial werden verschiedene Möglichkeiten fürwrite to a file using Java untersucht. Wir werdenBufferedWriter,PrintWriter,FileOutputStream,DataOutputStream,RandomAccessFile,FileChannel und Java 7Files verwenden Utility-Klasse.

Wir werden uns auch mit dem Sperren der Datei während des Schreibens befassen und einige letzte Hinweise zum Schreiben in eine Datei besprechen.

Dieser Artikel ist Teil vonthe “Java – Back to Basic” series hier am Beispiel.

Weitere Lektüre:

Java - Daten an eine Datei anhängen

Eine schnelle und praktische Anleitung zum Anhängen von Daten an Dateien.

Read more

FileNotFoundException in Java

Eine schnelle und praktische Anleitung zu FileNotFoundException in Java.

Read more

So kopieren Sie eine Datei mit Java

Sehen Sie sich einige gebräuchliche Methoden zum Kopieren von Dateien in Java an.

Read more

2. Schreiben Sie mitBufferedWriter

Beginnen wir einfach - und schreiben Sie mitBufferedWriterStringto a new file:

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 dannappend a String to the existing file:

@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 wird dann sein:

Hello World

3. Schreiben Sie mitPrintWriter

Weiter - sehen wir uns an, wie wir mitPrintWriter formatierten Text in eine Datei schreiben können:

@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 unformatierten String in eine Datei schreiben, sondern auch formatierten Text mit der Methodeprintf.

Wir können den Writer mitFileWriter,BufferedWriter oder sogarSystem.out erstellen.

4. Schreiben Sie mitFileOutputStream

Lassen Sie uns nun sehen, wie wirFileOutputStream biswrite binary data to a file verwenden können. Der folgende Code konvertiert die Int-Bytes vonString und schreibt die Bytes mitFileOutputStream in die 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 wird natürlich sein:

Hello

5. Schreiben Sie mitDataOutputStream

Weiter - Schauen wir uns an, wie wir mitDataOutputStream 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 mitRandomAccessFile

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 benötigen einen wahlfreien Zugriff.

RandomAccessFile ermöglichen es uns, an einer bestimmten Position in der Datei zu schreiben, wenn der Versatz - vom Anfang der Datei - in Bytes angegeben wird. Der folgende Code schreibt einen ganzzahligen Wert mit einem Offset, der am Anfang der Datei angegeben wird:

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 die folgende Methode anwenden:

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 sie - und lesen Sie 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 mitFileChannel

Wenn Sie mit großen Dateien arbeiten, könnenFileChannel schneller sein als Standard-E / A. Der folgende Code schreibtString mitFileChannel 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 mitFiles Klasse

Java 7 bietet eine neue Arbeitsweise mit dem Dateisystem sowie eine neue Dienstprogrammklasse -Files. Mit der KlasseFileskönnen wir auch Dateien und Verzeichnisse erstellen, verschieben, kopieren, 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. In eine temporäre Datei schreiben

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

@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 Sie sehen, ist es nur die Erstellung der temporären Datei, die interessant und anders ist. Nach diesem Zeitpunkt ist das Schreiben in die Datei dasselbe.

10. Datei vor dem Schreiben sperren

Schließlich müssen Sie beim Schreiben in eine Datei manchmal besonders darauf achten, dass nicht gleichzeitig jemand anderes in diese Datei schreibt. Grundsätzlich müssen Sie in der Lage sein, diese Datei beim Schreiben zu sperren.

Verwenden Sie dieFileChannel, um zu versuchen, die Datei zu sperren, bevor Sie darauf schreiben:

@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();
}

Beachten Sie, dass einOverlappingFileLockException ausgelöst wird, wenn die Datei bereits gesperrt ist, wenn wir versuchen, die Sperre zu erlangen.

11. Anmerkungen

Nachdem wir so viele Methoden zum Schreiben in eine Datei untersucht haben, wollen wir einige wichtige Hinweise besprechen:

  • Wenn wir versuchen, aus einer nicht vorhandenen Datei zu lesen, wird einFileNotFoundException ausgelöst

  • Wenn wir versuchen, in eine nicht vorhandene Datei zu schreiben, wird die Datei zuerst erstellt und es wird keine Ausnahme ausgelöst

  • Es ist sehr wichtig, den Stream nach seiner Verwendung zu schließen, da er nicht implizit geschlossen wird, um alle damit verbundenen Ressourcen freizugeben

  • Im Ausgabestream ruft die Methodeclose()flush() auf, bevor die Ressourcen freigegeben werden, wodurch alle gepufferten Bytes in den Stream geschrieben werden

Wenn wir uns die gängigen Verwendungspraktiken ansehen, können wir beispielsweise feststellen, dassPrintWriter zum Schreiben von formatiertem Text verwendet wird. FileOutputStream zum Schreiben von Binärdaten; DataOutputStream zum Schreiben primitiver Datentypen; RandomAccessFile, um an eine bestimmte Position zu schreiben; FileChannel, um in größeren Dateien schneller zu schreiben. Einige der APIs dieser Klassen erlauben mehr, aber dies ist ein guter Anfang.

12. Fazit

Dieser Artikel beschreibt die vielen Möglichkeiten, Daten mit Java in eine Datei zu schreiben.

Die Implementierung all dieser Beispiele und Codefragmentecan be found over on GitHub project - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein, wie es ist.