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.