Vodič za I / O u Groovyju

1. Uvod

Iako u Groovyju možemo raditi s I / O-om baš kao što radimo na Javi, Groovy proširuje Java-ovu I / O funkcionalnost brojnim pomoćnim metodama.

U ovom uputstvu pogledat ćemo čitanje i pisanje datoteka, prelazak datotečnih sustava i serializiranje podataka i objekata putem Groovy's Datoteka metode produženja.

Gdje je to moguće, povezat ćemo se s našim relevantnim Java člancima radi lakše usporedbe s Java ekvivalentom.

2. Čitanje datoteka

Groovy dodaje praktičnu funkcionalnost za čitanje datoteka u obliku svakiLine metode, metode za dobivanje BufferedReaders i InputStreams i načine za dobivanje svih podataka datoteke s jednim retkom koda.

Java 7 i Java 8 imaju sličnu podršku za čitanje datoteka na Javi.

2.1. Čitanje sa svakiLine

Kad se bavimo tekstualnim datotekama, često moramo pročitati svaki redak i obraditi ga. Groovy pruža prikladno proširenje za java.io.Datoteka s svakiLine metoda:

def lines = [] nova datoteka ('src / main / resources / ioInput.txt'). eachLine {line -> lines.add (line)}

Zatvaranje predviđeno za svakiLine također ima korisni neobavezni broj retka. Upotrijebimo broj retka za dobivanje samo određenih redaka iz datoteke:

def lineNoRange = 2..4 def lines = [] nova datoteka ('src / main / resources / ioInput.txt'). eachLine {line, lineNo -> if (lineNoRange.contens (lineNo)) {lines.add (line )}}

Prema zadanim postavkama numeriranje reda započinje u jedan. Možemo pružiti vrijednost koja će se koristiti kao broj prvog retka prosljeđivanjem kao prvi parametar parametru svakiLine metoda.

Počnimo s brojevima svojih linija s nule:

nova datoteka ('src / main / resources / ioInput.txt'). eachLine (0, {line, lineNo -> if (lineNoRange.contens (lineNo)) {lines.add (line)}})

Ako se unese iznimka svaka linija, Groovy osigurava da se resurs datoteka zatvori. Slično kao pokušajte s resursima ili a probaj-napokon na Javi.

2.2. Čitanje s Readerom

Također lako možemo dobiti BufferedReader iz Groovyja Datoteka objekt. Možemo koristiti withReader dobiti a BufferedReader na objekt datoteke i proslijedite ga zatvaranju:

def actualCount = 0 nova datoteka ('src / main / resources / ioInput.txt'). withReader {čitač -> dok (čitač.readLine ()) {actualCount ++}}

Kao i sa svakiLine, withReader metoda automatski će zatvoriti resurs kada se izuzme izuzetak.

Ponekad bismo možda željeli imati BufferedReader dostupan objekt. Na primjer, mogli bismo planirati pozvati metodu koja uzima jedan od njih kao parametar. Možemo koristiti newReader metoda za ovo:

def outputPath = 'src / main / resources / ioOut.txt' def reader = nova datoteka ('src / main / resources / ioInput.txt'). newReader () nova datoteka (outputPath) .append (čitač) reader.close ( )

Za razliku od ostalih metoda koje smo do sada gledali, odgovorni smo za zatvaranje BufferedReader resursa kad nabavljamo U međuspremnikČitač ovuda.

2.3. Čitanje sa InputStreams

Slično withReader i newReader, Groovy također nudi metode za lak rad InputStreams. Iako možemo čitati tekst s InputStreams i Groovy čak dodaju funkcionalnost za to, InputStreams se najčešće koriste za binarne podatke.

Iskoristimo withInputStream proći an InputStream do zatvaranja i u bajtovima pročitajte:

bajt [] data = [] nova datoteka ("src / main / resources / binaryExample.jpg"). withInputStream {stream -> data = stream.getBytes ()}

Ako trebamo imati InputStream objekt, možemo ga dobiti pomoću newInputStream:

def outputPath = 'src / main / resources / binaryOut.jpg' def is = nova datoteka ('src / main / resources / binaryExample.jpg'). newInputStream () nova datoteka (outputPath) .append (is) is.close ( )

Kao i kod BufferedReader, moramo zatvoriti našu InputStream kad se koristimo newInputStream, ali ne i kada se koristi withInputStream.

2.4. Čitanje na druge načine

Završimo temu čitanja gledajući nekoliko metoda koje Groovy ima za prikupljanje svih podataka datoteke u jednom iskazu.

Ako želimo retke naše datoteke u Popis, možemo koristiti prikupiti s iteratorom to prešlo na zatvaranje:

def actualList = nova datoteka ('src / main / resources / ioInput.txt'). prikupite {it}

Da bismo dobili linije naše datoteke u niz Žice, možemo koristiti kao niz []:

def actualArray = nova datoteka ('src / main / resources / ioInput.txt') kao niz []

Za kratke datoteke cjelokupan sadržaj možemo dobiti u Niz koristeći tekst:

def actualString = nova datoteka ('src / main / resources / ioInput.txt'). tekst

A kada radite s binarnim datotekama, postoji bajtova metoda:

def contents = nova datoteka ('src / main / resources / binaryExample.jpg'). bajtova

3. Pisanje datoteka

Prije nego što počnemo pisati u datoteke, postavimo tekst koji ćemo izlaziti:

def outputLines = ['Linija jedan iz izlaza primjera', 'Linija dva izlaza primjera', 'Linija tri izlaza primjera']

3.1. Pisanje s Writer-om

Kao i kod čitanja datoteke, lako možemo dobiti i BufferedWriter od a Datoteka objekt.

Iskoristimo withWriter dobiti a BufferedWriter i proslijedite ga zatvaranju:

def outputFileName = 'src / main / resources / ioOutput.txt' nova datoteka (outputFileName) .withWriter {Writer -> outputLines.each {line -> Writer.writeLine line}}

Koristeći withReader zatvorit će resurs ako se dogodi izuzetak.

Groovy također ima metodu za dobivanje BufferedWriter objekt. Uzmimo a BufferedWriter koristeći newWriter:

def outputFileName = 'src / main / resources / ioOutput.txt' def writer = nova datoteka (outputFileName) .newWriter () outputLines.forEach {line -> writer.writeLine line} writer.flush () writer.close ()

Odgovorni smo za ispiranje i zatvaranje BufferedWriter objekt kad koristimo newWriter.

3.2. Pisanje s izlaznim tokovima

Ako ispisujemo binarne podatke, možemo dobiti Izlazni tok koristeći bilo koji withOutputStream ili newOutputStream.

Napišimo nekoliko bajtova u datoteku pomoću withOutputStream:

byte [] outBytes = [44, 88, 22] nova datoteka (outputFileName) .withOutputStream {stream -> stream.write (outBytes)}

Nabavimo Izlazni tok objekt s newOutputStream i upotrijebite ga za pisanje nekih bajtova:

bajt [] outBytes = [44, 88, 22] def os = nova datoteka (outputFileName) .newOutputStream () os.write (outBytes) os.close ()

Slično kao InputStream, BufferedReader, i BufferedWriter, odgovorni smo za zatvaranje Izlazni tok sebe kada koristimo newOutputStream.

3.3. Pisanje s operatorom <<

Kako je pisanje teksta u datoteke toliko često, << operator pruža ovu značajku izravno.

Iskoristimo << operater za pisanje nekoliko jednostavnih redaka teksta:

def ln = System.getProperty ('line.separator') def outputFileName = 'src / main / resources / ioOutput.txt' new File (outputFileName) << "Red jedan od izlaznog primjera $ {ln}" + "Red dva od izlazni primjer $ {ln} redak tri izlaznog primjera "

3.4. Zapisivanje binarnih podataka bajtovima

Ranije smo vidjeli u članku da sve bajtove možemo dobiti iz binarne datoteke jednostavnim pristupom datoteci bajtova polje.

Napišimo binarne podatke na isti način:

def outputFileName = 'src / main / resources / ioBinaryOutput.bin' def outputFile = nova datoteka (outputFileName) bajt [] outBytes = [44, 88, 22] outputFile.bytes = outBytes

4. Prelazak drveća datoteka

Groovy nam također pruža jednostavne načine rada sa stablima datoteka. U ovom ćemo odjeljku to učiniti s svakaDatoteka, svakiDir i njihove inačice i prijeći metoda.

4.1. Popis datoteka sa svakaDatoteka

Navedimo sve datoteke i direktorije u direktoriju pomoću svakaDatoteka:

nova datoteka ('src / main / resources'). eachFile {datoteka -> println datoteka.name}

Sljedeći uobičajeni scenarij rada s datotekama je potreba za filtriranjem datoteka na temelju imena datoteke. Navedimo samo datoteke koje počinju s “io” i završavaju u “.txt” pomoću svakiFileMatch i regularni izraz:

nova datoteka ('src / main / resources'). eachFileMatch (~ / io. * \. txt /) {datoteka -> println datoteka.ime}

The svakaDatoteka i svakiFileMatch metode popisuju samo sadržaj direktorija najviše razine. Groovy nam također omogućuje da ograničimo ono što svakaDatoteka metode se vraćaju dodavanjem a Vrsta datoteke metodama. Opcije su BILO KOJE, DATOTEKE, i IMENICI.

Idemo rekurzivno navesti sve datoteke koje koriste eachFileRecurse i pružanje mu a Vrsta datoteke od DATOTEKE:

nova datoteka ('src / main'). eachFileRecurse (FileType.FILES) {datoteka -> println "$ file.parent $ file.name"}

The svakaDatoteka metode bacaju IlegalArgumentException ako im pružimo put do datoteke umjesto direktorija.

Groovy također nudi svakiDir metode za rad samo s direktorijima. Možemo koristiti svakiDir i njegove inačice za postizanje iste stvari kao i korištenje svakaDatoteka s Vrsta datoteke od IMENICI.

Ajmo rekurzivno navesti direktorijume sa eachFileRecurse:

nova datoteka ('src / main'). eachFileRecurse (FileType.DIRECTORIES) {datoteka -> println "$ file.parent $ file.name"}

Sada, učinimo istu stvar sa svakiDirRecurse:

nova datoteka ('src / main'). eachDirRecurse {dir -> println "$ dir.parent $ dir.name"}

4.2. Popis datoteka s Traverseom

Za složenije slučajeve uporabe direktorija za obilazak možemo koristiti prijeći metoda. Djeluje slično kao eachFileRecurse ali pruža mogućnost povratka FileVisitResult predmeti za kontrolu obrade.

Iskoristimo prijeći na naš src / glavni direktorija i preskočite obradu stabla pod groovy imenik:

nova datoteka ('src / main'). prelazak {datoteke -> ako (datoteka.direktorij && file.name == 'groovy') {FileVisitResult.SKIP_SUBTREE} else {println "$ file.parent - $ file.name"} }

5. Rad s podacima i objektima

5.1. Serijaliziranje primitiva

U Javi možemo koristiti DataInputStream i DataOutputStream za serializaciju primitivnih polja podataka. Groovy i ovdje dodaje korisna proširenja.

Postavimo neke primitivne podatke:

String message = 'Ovo je serializirani niz' int length = message.length () boolean valid = true

Ajmo sada serializirati svoje podatke u datoteku pomoću withDataOutputStream:

nova datoteka ('src / main / resources / ioData.txt'). withDataOutputStream {out -> out.writeUTF (poruka) out.writeInt (length) out.writeBoolean (valid)}

I pročitajte ga ponovno u upotrebi withDataInputStream:

String loadedMessage = "" int loadedLength boolean loadedValid nova datoteka ('src / main / resources / ioData.txt'). WithDataInputStream {is -> loadedMessage = is.readUTF () loadedLength = is.readInt () loadedValid = is.readBoolean )}

Slično drugom s* metode, withDataOutputStream i withDataInputStream prenesite tok do zatvarača i osigurajte da je pravilno zatvoren.

5.2. Serijaliziranje objekata

Groovy se također nadovezuje na Java ObjectInputStream i ObjectOutputStream kako bi nam omogućili jednostavnu serializaciju objekata koji se implementiraju Serijalizirati.

Prvo definirajmo klasu koja implementira Serijalizirati:

klasa Zadatak implementira Serializable {Opis niza Datum startDate Datum dueDate int status}

Ajmo sada stvoriti instancu Zadatak da možemo serializirati u datoteku:

Zadatak zadatka = novi zadatak (opis: 'Iznesite smeće', startDate: novi datum (), status: 0)

S našim Zadatak objekt u ruci, ajmo ga serializirati u datoteku pomoću withObjectOutputStream:

nova datoteka ('src / main / resources / ioSerializedObject.txt'). withObjectOutputStream {out -> out.writeObject (zadatak)}

Napokon, pročitajmo naše Zadatak natrag u korištenju withObjectInputStream:

Zadatak taskRead new File ('src / main / resources / ioSerializedObject.txt'). WithObjectInputStream {je -> taskRead = is.readObject ()}

Metode koje smo koristili, withObjectOutputStream i withObjectInputStream, proslijedite tok do zatvaranja i rukujete zatvaranjem resursa na odgovarajući način, baš kao što je slučaj s drugim s* metode.

6. Zaključak

U ovom smo članku istražili funkcionalnost koju Groovy dodaje postojećim I / O klasama Java File. Ovu smo funkcionalnost koristili za čitanje i pisanje datoteka, rad sa strukturama direktorija i serializaciju podataka i objekata.

Dotaknuli smo se samo nekoliko pomoćnih metoda, pa vrijedi kopati po Groovyjevoj dokumentaciji da vidimo što još dodaje Javinoj I / O funkcionalnosti.

Primjer koda dostupan je na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found