Java - Skriv til fil

1. Oversikt

I denne veiledningen, vi vil utforske forskjellige måter å skrive til en fil ved hjelp av Java. Vi bruker BufferedWriter, PrintWriter, FileOutputStream, DataOutputStream, RandomAccessFile, FileChannel, og Java 7 Filer bruksklasse.

Vi vil også se på å låse filen mens du skriver og diskutere noen endelige takeaways når du skriver til filen.

Denne opplæringen er en del av Java "Back to Basics" -serien her på Baeldung.

2. Skriv med BufferedWriter

La oss starte enkelt og bruk BufferedWriter å skrive en String til en ny fil:

offentlig ugyldig nårWriteStringUsingBufferedWritter_thenCorrect () kaster IOException {String str = "Hello"; BufferedWriter skribent = ny BufferedWriter (ny FileWriter (filnavn)); writer.write (str); writer.close (); }

Utdataene i filen vil være:

Hallo

Vi kan da legge til en String til den eksisterende filen:

@Test offentlig ugyldig når AppendStringUsingBufferedWritter_thenOldContentShouldExistToo () kaster IOException {String str = "World"; BufferedWriter-forfatter = ny BufferedWriter (ny FileWriter (filnavn, sant)); writer.append (''); author.append (str); writer.close (); }

Filen vil da være:

Hei Verden

3. Skriv med PrintWriter

La oss se hvordan Vi kan bruke PrintWriter for å skrive formatert tekst til en fil:

@Test offentlig ugyldig givenWritingStringToFile_whenUsingPrintWriter_thenCorrect () kaster IOException {FileWriter fileWriter = ny FileWriter (filnavn); PrintWriter printWriter = ny PrintWriter (fileWriter); printWriter.print ("Noen strenger"); printWriter.printf ("Produktnavnet er% s og prisen er% d $", "iPhone", 1000); printWriter.close (); }

Den resulterende filen vil inneholde:

Noen navn på strengprodukter er iPhone og prisen er 1000 $

Legg merke til hvordan vi ikke bare skriver en råvare String til en fil, men også noe formatert tekst med printf metode.

Vi kan lage forfatteren ved hjelp av FileWriter, BufferedWriter, eller System.out.

4. Skriv med FileOutputStream

La oss nå se hvordan vi kan bruke FileOutputStream til skrive binære data til en fil.

Følgende kode konverterer a String i byte og skriver byte til en fil ved hjelp av FileOutputStream:

@Test offentlig ugyldig givenWritingStringToFile_whenUsingFileOutputStream_thenCorrect () kaster IOException {String str = "Hello"; FileOutputStream outputStream = ny FileOutputStream (filnavn); byte [] strToBytes = str.getBytes (); outputStream.write (strToBytes); outputStream.close (); }

Utdataene i filen vil selvfølgelig være:

Hallo

5. Skriv med DataOutputStream

Deretter, la oss ta en titt på hvordan vi kan bruke DataOutputStream å skrive en String til en fil:

@Test offentlig ugyldighet givenWritingToFile_whenUsingDataOutputStream_thenCorrect () kaster IOException {String value = "Hello"; FileOutputStream fos = ny FileOutputStream (filnavn); DataOutputStream outStream = ny DataOutputStream (ny BufferedOutputStream (fos)); outStream.writeUTF (verdi); outStream.close (); // verifisere resultatene Stringresultat; FileInputStream fis = ny FileInputStream (filnavn); DataInputStream-leser = ny DataInputStream (fis); resultat = reader.readUTF (); reader.close (); assertEquals (verdi, resultat); }

6. Skriv med RandomAccessFile

La oss nå illustrere hvordan skrive og redigere i en eksisterende fil i stedet for bare å skrive til en helt ny fil eller legge til en eksisterende. Enkelt sagt: Vi trenger tilfeldig tilgang.

RandomAccessFile gjør det mulig for oss å skrive på en bestemt plassering i filen gitt forskyvningen - fra begynnelsen av filen - i byte.

Denne koden skriver et heltall med offset gitt fra begynnelsen av filen:

privat ugyldig writeToPosition (streng filnavn, int data, lang posisjon) kaster IOException {RandomAccessFile skribent = ny RandomAccessFile (filnavn, "rw"); writer.seek (stilling); writer.writeInt (data); writer.close (); }

Hvis vi vil les int lagret på et bestemt sted, kan vi bruke denne metoden:

privat int readFromPosition (strengfilnavn, lang posisjon) kaster IOException {int resultat = 0; RandomAccessFile reader = ny RandomAccessFile (filnavn, "r"); reader.seek (stilling); resultat = reader.readInt (); reader.close (); returresultat; }

For å teste funksjonene våre, la oss skrive et heltall, redigere det og til slutt lese det tilbake:

@Test offentlig ugyldig når WritingToSpecificPositionInFile_thenCorrect () kaster IOException {int data1 = 2014; int data2 = 1500; writeToPosition (filnavn, data1, 4); assertEquals (data1, readFromPosition (filnavn, 4)); skriv til posisjon (filnavn2, data2, 4); assertEquals (data2, readFromPosition (filnavn, 4)); }

7. Skriv med FileChannel

Hvis vi har å gjøre med store filer, FileChannel kan være raskere enn standard IO. Følgende kode skriver String til en fil ved hjelp av FileChannel:

@Test offentlig ugyldig givenWritingToFile_whenUsingFileChannel_thenCorrect () kaster IOException {RandomAccessFile stream = new RandomAccessFile (fileName, "rw"); FileChannel channel = stream.getChannel (); Strengverdi = "Hei"; byte [] strBytes = value.getBytes (); ByteBuffer buffer = ByteBuffer.allocate (strBytes.length); buffer.put (strBytes); buffer.flip (); channel.write (buffer); stream.close (); channel.close (); // verifisere RandomAccessFile-leser = ny RandomAccessFile (filnavn, "r"); assertEquals (verdi, reader.readLine ()); reader.close (); }

8. Skriv med Filer Klasse

Java 7 introduserer en ny måte å jobbe med filsystemet sammen med en ny verktøysklasse: Filer.

Bruker Filer klasse, kan vi opprette, flytte, kopiere og slette filer og kataloger. Den kan også brukes til å lese og skrive til en fil:

@Test offentlig ugyldighet givenUsingJava7_whenWritingToFile_thenCorrect () kaster IOException {String str = "Hello"; Sti bane = Paths.get (fileName); byte [] strToBytes = str.getBytes (); Files.write (sti, strToBytes); Streng lese = Files.readAllLines (sti) .get (0); assertEquals (str, read); }

9. Skriv til en midlertidig fil

La oss nå prøve å skrive til en midlertidig fil. Følgende kode oppretter en midlertidig fil og skriver a String til det:

@Test offentlig ugyldig nårWriteToTmpFile_thenCorrect () kaster IOException {String toWrite = "Hei"; File tmpFile = File.createTempFile ("test", ".tmp"); FileWriter-forfatter = ny FileWriter (tmpFile); writer.write (toWrite); writer.close (); BufferedReader reader = ny BufferedReader (ny FileReader (tmpFile)); assertEquals (toWrite, reader.readLine ()); reader.close (); }

Som vi kan se, er det bare opprettelsen av den midlertidige filen som er interessant og annerledes. Etter det punktet er det samme å skrive til filen.

10. Lås filen før du skriver

Til slutt, når vi skriver til en fil, må vi noen ganger være ekstra sikre på at ingen andre skriver til den filen samtidig. I utgangspunktet må vi kunne låse den filen mens du skriver.

La oss gjøre bruk av FileChannel for å prøve å låse filen før du skriver til den:

@Test offentlig ugyldig når TryToLockFile_thenItShouldBeLocked () kaster IOException {RandomAccessFile stream = new RandomAccessFile (fileName, "rw"); FileChannel channel = stream.getChannel (); FileLock-lås = null; prøv {lock = channel.tryLock (); } fange (endelig OverlappingFileLockException e) {stream.close (); channel.close (); } stream.writeChars ("testlås"); lock.release (); stream.close (); channel.close (); }

Merk at hvis filen allerede er låst når vi prøver å anskaffe låsen, vil en OverlappingFileLockException vil bli kastet.

11. Merknader

Etter å ha utforsket så mange metoder for å skrive til en fil, la oss diskutere noen viktige merknader:

  • Hvis vi prøver å lese fra en fil som ikke eksisterer, a FileNotFoundException vil bli kastet.
  • Hvis vi prøver å skrive til en fil som ikke eksisterer, opprettes filen først, og intet unntak blir kastet.
  • Det er veldig viktig å lukke strømmen etter å ha brukt den, da den ikke er stengt implisitt, for å frigjøre ressurser knyttet til den.
  • I utgangsstrømmen Lukk() metode samtaler flush () før du frigjør ressursene, som tvinger eventuelle bufrede byte til å skrives til strømmen.

Ser vi på vanlige bruksrutiner, kan vi for eksempel se det PrintWriter brukes til å skrive formatert tekst, FileOutputStream å skrive binære data, DataOutputStream å skrive primitive datatyper, RandomAccessFile å skrive til en bestemt posisjon, og FileChannel for å skrive raskere i større filer. Noen av APIene i disse klassene tillater mer, men dette er et godt sted å starte.

12. Konklusjon

Denne artikkelen illustrerte de mange alternativene for å skrive data til en fil ved hjelp av Java.

Implementeringen av alle disse eksemplene og kodebiter finner du på GitHub.