Java - Skriv till fil

1. Översikt

I den här handledningen utforskar vi olika sätt att skriva till en fil med Java. Vi använder oss av BufferedWriter , PrintWriter , FileOutputStream , DataOutputStream , RandomAccessFile , FileChannel och Java 7 Files- verktygsklassen.

Vi kommer också att titta på att låsa filen medan du skriver och diskutera några sista takeaways när du skriver till filen.

Denna handledning är en del av Java "Back to Basics" -serien här på Baeldung.

2. Skriv med BufferedWriter

Låt oss börja enkelt och använda BufferedWriter för att skriva en sträng till en ny fil :

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

Utdata i filen blir:

Hello

Vi kan sedan lägga till en sträng till den befintliga filen :

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

Filen blir då:

Hello World

3. Skriv med PrintWriter

Låt oss sedan se hur vi kan använda PrintWriter för att skriva formaterad text till en fil :

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

Den resulterande filen kommer att innehålla:

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

Observera hur vi inte bara skriver en rå sträng till en fil utan också lite formaterad text med printf- metoden.

Vi kan skapa författaren med FileWriter , BufferedWriter eller till och med System.out .

4. Skriv med FileOutputStream

Låt oss nu se hur vi kan använda FileOutputStream för att skriva binär data till en fil.

Följande kod konverterar en sträng till byte och skriver byten till en fil med FileOutputStream :

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

Utdata i filen kommer naturligtvis att vara:

Hello

5. Skriv med DataOutputStream

Låt oss sedan titta på hur vi kan använda DataOutputStream för att skriva en sträng till en fil:

@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. Skriv med RandomAccessFile

Låt oss nu illustrera hur man skriver och redigerar i en befintlig fil snarare än att bara skriva till en helt ny fil eller lägga till en befintlig fil. Enkelt uttryckt: Vi behöver slumpmässig åtkomst.

RandomAccessFile gör det möjligt för oss att skriva på en specifik position i filen med förskjutning - från början av filen - i byte.

Den här koden skriver ett heltal med offset från början av filen:

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

Om vi ​​vill läsa int lagrad på en viss plats kan vi använda den här metoden:

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; }

För att testa våra funktioner, låt oss skriva ett heltal, redigera det och slutligen läsa det tillbaka:

@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. Skriv med FileChannel

Om vi ​​har att göra med stora filer kan FileChannel vara snabbare än standard IO. Följande kod skriver sträng till en fil med FileChannel :

@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. skriver med filer Class

Java 7 introducerar ett nytt sätt att arbeta med filsystemet tillsammans med en ny verktygsklass: Files .

Med filklassen kan vi skapa, flytta, kopiera och ta bort filer och kataloger. Den kan också användas för att läsa och skriva till en fil:

@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. Skriv till en tillfällig fil

Låt oss nu försöka skriva till en tillfällig fil. Följande kod skapar en tillfällig fil och skriver en sträng till den:

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

Som vi kan se är det bara skapandet av den tillfälliga filen som är intressant och annorlunda. Efter den tiden är det samma att skriva till filen.

10. Lås filen innan du skriver

Slutligen, när vi skriver till en fil, måste vi ibland vara extra säkra på att ingen annan skriver till den filen samtidigt. I grund och botten måste vi kunna låsa den filen medan vi skriver.

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.

Implementeringen av alla dessa exempel och kodavsnitt finns på GitHub.