16. diel - Práca s vlastnými súbormi v Kotlin - ZIP archív
V minulej lekcii, Práca so súbormi a priečinkami v Kotlin - Nové API , sme si ukázali prácu so súbormi a priečinkami v Kotline pomocou tried zavedených od Javy 7.
Teraz už vieme pracovať s množstvom druhov súborov. Vieme, ako ich ukladať a otvárať, prehrávať, odchytávať chyby. V dnešnom dieli nášho Kotlin tutoriálu si ukážeme ďalšiu možnosť práce so súbormi, a to s použitím ZIP archívu.
Zip archívy
Predstavme si reálnu aplikáciu na evidenciu zamestnancov. Zamestnanec v nej má textové údaje (meno, priezvisko a email), dátum (dátum narodenia), číslo (telefónne číslo) a obrázok (fotografiu). Už len kvôli obrázku môže byť na prvý pohľad problém všetky tieto dáta uložiť, a to ideálne do jedného jediného súboru. Teoreticky by sme mohli zvoliť nejaký binárny formát dát (kvôli obrázku) a vložiť do neho aj textové údaje. Prakticky sú ale binárne súbory pomerne nešikovné a zle sa s nimi reaguje na zmeny formátu.
Podobné aplikácie často využívajú na ukladanie dát archívy. Zoberme
si taký MS-Word a jeho dokumenty s príponou súborov .docx
. Keď
zmeníme príponu ľubovoľného .docx
súboru na
.zip
, zistíme, že dokument je v skutočnosti archív ZIP, iba s
inou príponou. Skúste si to.
Windows skrývajú v predvolenom nastavení prípony súborov
známych typov, takže namiesto Dokument.docx
vidíme len
Dokument
. Nastavenie zmeníme v záložke Zobrazenie, v
okne Zobraziť či skryť zaškrtnutím políčka Prípony názvov
súborov.
Ako archív v sebe môže súbor obsahovať jednoducho niekoľko súborov a
navonok sa tvári pre nič netušiaceho užívateľa ako jeden. Presne archívu
ZIP využijeme aj na uloženie nášho zamestnanca. A namiesto .zip
nastavíme súboru úplne inú príponu, ponúka sa .zamestnanec
alebo skrátene .zam
.
Prípona súboru slúži len na to, aby operačný systém Windows zistil, v akej aplikácii má súbor otvoriť, keď naň používateľ poklepe. Väčšinou platí, že má každý súbor na konci svojho názvu bodku a trojpísmenovú príponu. V skutočnosti nemusí mať súbor príponu vôbec žiadnu, môže ich mať viac, môžu byť dlhšie ako tri znaky a dokonca nemusia vôbec zodpovedať tomu, čo je v súbore uložené.
My budeme súbor .zip
maskovať ako súbor .zam
.
Zips neponecháme z toho dôvodu, aby to používateľa nesmiatlo a nezačal
súbory rozbaľovať a meniť.
Formát súborov .zam
Štruktúra zazipovanej zložky bude nasledovná:
data.zam
zamestnanci.xml
obrazky/
jmenoprijmeni_1.png
jmenoprijmeni_2.png
zamestnanci.xml
bude vyzerať napríklad takto:
<zamestnanci> <zamestnanec> <jmeno>Tomáš</jmeno> <prijmeni>Šeldosklepa</prijmeni> <email>[email protected]</email> <telefon>123456789</telefon> <narozeni>1.1.1970</narozeni> </zamestnanec> </zamestnanci>
Element <zamestnanci>
obaľujúci
zamestnancov je tu preto, že aplikácia môže niekedy v budúcnosti
spracovávať viac zamestnancov. Nad takými "drobnosťami" je potrebné pri
návrhu premýšľať.
Tvorba aplikácie
Vytvorme si nový projekt, formulárovú aplikáciu. Pod článkom je k dispozícii archív s projektom. V projekte už sú vygenerované všetky potrebné formulárové prvky a navesené obsluhy tlačidiel:
Trieda Zamestnanec
Začneme tým, čo by malo byť jasné, teda vlastnosťami. Náš zamestnanec bude mať:
- meno,
- priezvisko,
- email,
- telefón,
- dátum narodenia
- a bude mať aj fotografiu.
toString()
, celý kód potom
vyzerá takto:
class Zamestnanec @JvmOverloads constructor( var jmeno: String = "", var prijmeni: String = "", var email: String = "", var telefon: String = "", var narozeniny: LocalDate = LocalDate.now() ) { var obrazek: BufferedImage? = null override fun toString(): String { return "Zamestnanec{jmeno=$jmeno, prijmeni=$prijmeni}" } }
Konštruktor sme označili anotáciou @JvmOverloads
, pretože ho
použijeme na dve preťaženia. Prvé preťaženie vytvorí prázdneho
zamestnanca. Pomocou druhého vytvoríme inštanciu zamestnanca so všetkými
údajmi, okrem obrázku. Anotáciou @JvmOverloads
potom zaistíme
interoperabilitu s Javou, kde by sme museli deklarovať konštruktorov
dvoch.
Úprava kontroléra
Do projektu si teraz pridáme kontrolér DatabazeKontroler
a
deklarujeme v ňom kolekciu zamestnancov a jednotlivé položky z
formulára:
class DatabazeKontroler { private val zamestnanci = mutableListOf<Zamestnanec>() @FXML private lateinit var obrazekView: ImageView @FXML private lateinit var jmenoTextField: TextField @FXML private lateinit var prijmeniTextField: TextField @FXML private lateinit var emailTextField: TextField @FXML private lateinit var telefonTextField: TextField @FXML private lateinit var datumPicker: DatePicker }
Metódy pre obsluhu tlačidiel
Ďalej si pripravíme metódu na načítanie obrázku:
@FXML private fun nacistObrazek() { val fileChooser = FileChooser() // Vytvoření průzkumníka souborů val soubor: File = fileChooser.showOpenDialog(Stage()) // Otevření dialogového okna průzkumníka souborů val obrazekURL: URL = soubor.toURI().toURL() // Vytvoření URL cesty k souboru val obrazek = Image(obrazekURL.toExternalForm()) // Získání obrázku - .png, .jpg, .jpeg... obrazekView.image = obrazek // Zobrazení vybraného obrázku }
Pomocou metódy FileChooser()
vytvoríme prieskumníka súborov,
ktorý nám následne umožní vybrať súbor s obrázkom. Do pomocnej premennej
si uložíme cestu k obrázku, ktorý následne vytvoríme pomocou triedy
Image()
. Nakoniec ho zobrazíme v našom formulári.
Doplníme tiež metódu, ktorá bude slúžiť na ukladanie užívateľov:
@FXML private fun ulozZaznam() { val jmeno = jmenoTextField.text val prijmeni = prijmeniTextField.text val email = emailTextField.text val telCislo = telefonTextField.text /** * Nejdříve získáme hodnotu z DatePicker novyUzivatelDatumRegistrace, * Poté získáme den, měsíc a rok. Nakonec vytvoříme datum ve formátu "den'.'Měsíc'.'Rok" */ val datePickerValue = datumPicker.value val den = datePickerValue.dayOfMonth.toString() val mesic = datePickerValue.monthValue.toString() val rok = datePickerValue.year.toString() val datum = "${den}.${mesic}.${rok}" val datumNarozenin: LocalDate = LocalDate.parse(datum, DateTimeFormatter.ofPattern("d'.'M'.'y")) val uzivatel = Zamestnanec(jmeno, prijmeni, email, telCislo, datumNarozenin) // Vytvoření nového zaměstnance val obrazek = obrazekView.image uzivatel.obrazek = SwingFXUtils.fromFXImage( obrazek, null ) // SwingFXUtils - Přeloží JavaFX Image do BufferedImage zamestnanci.add(uzivatel) val fileChooser = FileChooser() // Vytvoření průzkumníku souborů fileChooser.title = "Uložit soubor" fileChooser.extensionFilters.addAll(FileChooser.ExtensionFilter("All Files", "*.*")) val soubor = fileChooser.showSaveDialog(Stage()) }
Kód oboch metód by mal byť zrozumiteľný, za zmienku stojí použitie
SwingFXUtils
pre prevedenie obrázku do formátu
BufferedImage
.
Prejdime teda k poslednej metóde na obsluhu tlačidiel nášho formulára na
načítanie záznamov. V metóde nacistZaznam()
bude možné
vybrať súbor, ktorý chceme načítať a potom zavoláme metódu
zobrazUzivatele()
, ktorú si vzápätí doplníme:
@FXML private fun nacistZaznam() { val fileChooser = FileChooser() // Vytvoření průzkumníku souborů val soubor: File = fileChooser.showOpenDialog(Stage()) // Otevření dialogového okna průzkumníka souborů zobrazUzivatele() }
Metóda zobrazUzivatele()
Po načítaní súboru necháme vo formulári vypísať používateľa, ktorý bol do kolekcie uložený ako prvý:
private fun zobrazUzivatele(){ jmenoTextField.text = zamestnanci.get(0).jmeno prijmeniTextField.text = zamestnanci.get(0).prijmeni emailTextField.text = zamestnanci.get(0).email datumPicker.value = zamestnanci.get(0).narozeniny telefonTextField.text = zamestnanci.get(0).telefon obrazekView.image = SwingFXUtils.toFXImage(zamestnanci.get(0).obrazek, null) // Pomocí SwingFXUtils opět přeložíme BufferedImage pro zobrazení v JavaFX }
Teraz máme aplikáciu navrhnutú. Samotné ukladanie a načítanie ZIP archívu si ukážeme a doplníme nabudúce.
V budúcej lekcii, Práca s vlastnými súbormi v Kotlin - XML pre ZIP archív , budeme pokračovať v príprave formulárovej aplikácie na ukladanie a načítanie ZIP súborov. Doplníme si do nej triedy na spracovanie údajov o zamestnancoch v XML formáte.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 3x (37.34 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Kotlin