Java - Napiši u datoteku

1. Pregled

U ovom vodiču, istražit ćemo različite načine pisanja u datoteku pomoću Jave. Iskoristit ćemo BufferedWriter, PrintWriter, FileOutputStream, DataOutputStream, RandomAccessFile, FileChannel, i Java 7 Datoteke klasa korisnosti.

Također ćemo pogledati zaključavanje datoteke tijekom pisanja i raspravit ćemo neke posljednje izmjene prilikom pisanja u datoteku.

Ovaj je vodič dio serije Java "Povratak osnovama" ovdje na Baeldungu.

2. Napišite s BufferedWriter

Krenimo jednostavno i koristiti BufferedWriter napisati a Niz u novu datoteku:

javna praznina kadaWriteStringUsingBufferedWritter_thenCorrect () baca IOException {String str = "Hello"; BufferedWriter Writer = novi BufferedWriter (novi FileWriter (fileName)); pisac.write (str); pisac.close (); }

Izlaz u datoteci bit će:

zdravo

Tada možemo dodati a Niz u postojeću datoteku:

@Test public void whenAppendStringUsingBufferedWritter_thenOldContentShouldExistToo () baca IOException {String str = "World"; BufferedWriter Writer = novi BufferedWriter (novi FileWriter (fileName, true)); pisac.append (''); pisac.append (str); pisac.close (); }

Datoteka će tada biti:

Pozdrav svijete

3. Napišite s PrintWriter

Dalje, da vidimo kako možemo koristiti PrintWriter za pisanje formatiranog teksta u datoteku:

@Test public void givenWritingStringToFile_whenUsingPrintWriter_thenCorrect () baca IOException {FileWriter fileWriter = new FileWriter (fileName); PrintWriter printWriter = novi PrintWriter (fileWriter); printWriter.print ("Neki niz"); printWriter.printf ("Naziv proizvoda je% s, a cijena mu je% d $", "iPhone", 1000); printWriter.close (); }

Dobivena datoteka sadržavat će:

Naziv nekog gudačkog proizvoda je iPhone, a cijena mu je 1000 USD

Imajte na umu kako ne pišemo samo raw Niz u datoteku, ali i neki formatirani tekst s printf metoda.

Pisca možemo stvoriti pomoću FileWriter, BufferedWriter, ili čak System.out.

4. Napišite s FileOutputStream

Pogledajmo sada kako se možemo koristiti FileOutputStream do zapis binarnih podataka u datoteku.

Sljedeći kod pretvara a Niz u bajtove i zapisuje bajtove u datoteku pomoću FileOutputStream:

@Test javna praznina givenWritingStringToFile_whenUsingFileOutputStream_thenCorrect () baca IOException {String str = "Hello"; FileOutputStream outputStream = novi FileOutputStream (fileName); bajt [] strToBytes = str.getBytes (); outputStream.write (strToBytes); outputStream.close (); }

Izlaz u datoteci će naravno biti:

zdravo

5. Napišite s DataOutputStream

Dalje, pogledajmo kako se možemo koristiti DataOutputStream napisati a Niz u datoteku:

@Test public void givenWritingToFile_whenUsingDataOutputStream_thenCorrect () baca IOException {String value = "Hello"; FileOutputStream fos = novi FileOutputStream (ime datoteke); DataOutputStream outStream = novi DataOutputStream (novi BufferedOutputStream (fos)); outStream.writeUTF (vrijednost); outStream.close (); // provjera rezultata String rezultat; FileInputStream fis = novi FileInputStream (ime datoteke); DataInputStream čitač = novi DataInputStream (fis); rezultat = čitač.readUTF (); čitač.close (); assertEquals (vrijednost, rezultat); }

6. Napišite s RandomAccessFile

Ajmo sada ilustrirati kako pisanje i uređivanje unutar postojeće datoteke a ne samo pisanje u potpuno novu datoteku ili dodavanje postojećoj. Jednostavno rečeno: potreban nam je slučajan pristup.

RandomAccessFile omogućuje nam pisanje na određeno mjesto u datoteci s obzirom na odmak - od početka datoteke - u bajtovima.

Ovaj kod zapisuje cjelobrojnu vrijednost s pomakom datim s početka datoteke:

private void writeToPosition (naziv datoteke datoteke, int podaci, duga pozicija) baca IOException {RandomAccessFile Writer = novi RandomAccessFile (naziv datoteke, "rw"); književnik.tražiti (položaj); Writer.WriteInt (podaci); pisac.close (); }

Ako želimo čitati int pohranjeni na određenom mjestu, možemo koristiti ovu metodu:

private int readFromPosition (naziv datoteke niza, duga pozicija) baca IOException {int rezultat = 0; Čitač RandomAccessFile = novi RandomAccessFile (naziv datoteke, "r"); čitač.tražiti (položaj); rezultat = čitač.readInt (); čitač.close (); povratni rezultat; }

Da bismo testirali svoje funkcije, napišimo cijeli broj, uredimo ga i na kraju čitamo:

@Test public void whenWritingToSpecificPositionInFile_thenCorrect () baca IOException {int data1 = 2014; int podaci2 = 1500; writeToPosition (Ime datoteke, podaci1, 4); assertEquals (data1, readFromPosition (Ime datoteke, 4)); writeToPosition (Ime datoteke2, podaci2, 4); assertEquals (data2, readFromPosition (Ime datoteke, 4)); }

7. Napišite s FileChannel

Ako imamo posla s velikim datotekama, FileChannel može biti brži od standardnog IO-a. Sljedeći kod piše Niz u datoteku pomoću FileChannel:

@Test public void givenWritingToFile_whenUsingFileChannel_thenCorrect () baca IOException {RandomAccessFile stream = new RandomAccessFile (fileName, "rw"); FileChannel channel = stream.getChannel (); Vrijednost niza = "Pozdrav"; bajt [] strBytes = value.getBytes (); ByteBuffer međuspremnik = ByteBuffer.allocate (strBytes.length); buffer.put (strBytes); buffer.flip (); channel.write (međuspremnik); stream.close (); channel.close (); // provjera RandomAccessFile čitač = novi RandomAccessFile (ime datoteke, "r"); assertEquals (value, reader.readLine ()); čitač.close (); }

8. Napišite s Datoteke Razred

Java 7 predstavlja novi način rada s datotečnim sustavom, zajedno s novom korisnom klasom: Datoteke.

Koristiti Datoteke klase, možemo stvarati, premještati, kopirati i brisati datoteke i direktorije. Također se može koristiti za čitanje i pisanje u datoteku:

@Test javna praznina givenUsingJava7_whenWritingToFile_thenCorrect () baca IOException {String str = "Hello"; Put puta = Paths.get (ime datoteke); bajt [] strToBytes = str.getBytes (); Files.write (put, strToBytes); Čitanje niza = Files.readAllLines (put) .get (0); assertEquals (str, čitanje); }

9. Zapiši u privremenu datoteku

Pokušajmo sada zapisivati ​​u privremenu datoteku. Sljedeći kod stvara privremenu datoteku i piše Niz tome:

@Test public void whenWriteToTmpFile_thenCorrect () baca IOException {String toWrite = "Hello"; Datoteka tmpFile = File.createTempFile ("test", ".tmp"); FileWriter Writer = novi FileWriter (tmpFile); pisac.write (toWrite); pisac.close (); Čitač BufferedReader = novi BufferedReader (novi FileReader (tmpFile)); assertEquals (toWrite, reader.readLine ()); čitač.close (); }

Kao što vidimo, samo je stvaranje privremene datoteke zanimljivo i drugačije. Nakon te točke pisanje u datoteku je isto.

10. Zaključajte datoteku prije pisanja

Konačno, kad pišemo u datoteku, ponekad moramo biti sigurni da nitko drugi istovremeno ne piše u tu datoteku. U osnovi, moramo biti u mogućnosti zaključati tu datoteku tijekom pisanja.

Iskoristimo FileChannel da biste pokušali zaključati datoteku prije pisanja u nju:

@Test public void whenTryToLockFile_thenItShouldBeLocked () baca IOException {RandomAccessFile stream = new RandomAccessFile (fileName, "rw"); FileChannel channel = stream.getChannel (); Zaključavanje FileLock = null; pokušajte {lock = channel.tryLock (); } catch (final OverlappingFileLockException e) {stream.close (); channel.close (); } stream.writeChars ("test lock"); lock.release (); stream.close (); channel.close (); }

Imajte na umu da ako je datoteka već zaključana kada pokušavamo doći do zaključavanja, datoteka OverlappingFileLockException bit će bačen.

11. Bilješke

Nakon što smo istražili toliko metoda pisanja u datoteku, razgovarajmo o nekim važnim napomenama:

  • Ako pokušamo čitati iz datoteke koja ne postoji, a FileNotFoundException bit će bačen.
  • Ako pokušamo zapisati u datoteku koja ne postoji, datoteka će se prvo stvoriti i neće biti izuzetaka.
  • Vrlo je važno zatvoriti tok nakon što ga koristite, jer nije implicitno zatvoren, kako biste oslobodili sve resurse povezane s njim.
  • U izlaznom toku, Zatvoriti() pozivi metode isprati () prije puštanja resursa, što prisiljava sve baferirane bajtove da se upišu u tok.

Gledajući uobičajene prakse korištenja, možemo vidjeti, na primjer, to PrintWriter koristi se za pisanje formatiranog teksta, FileOutputStream za pisanje binarnih podataka, DataOutputStream za pisanje primitivnih tipova podataka, RandomAccessFile pisati na određeno mjesto i FileChannel za brže pisanje u veće datoteke. Neki API-ji ovih klasa dopuštaju više, ali ovo je dobro mjesto za početak.

12. Zaključak

Ovaj je članak ilustrirao mnoge mogućnosti pisanja podataka u datoteku pomoću Jave.

Provedbu svih ovih primjera i isječaka koda možete pronaći na GitHubu.