Zarábaj až 6 000 € mesačne! Akreditované rekvalifikačné kurzy od 0 €. Viac informácií.

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
Súbor 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:

Formulár pre správu zamestnancov - Súbory a práce s nimi v Kotlin

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.
V triede si ešte prepíšeme metódu 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

 

Predchádzajúci článok
Práca so súbormi a priečinkami v Kotlin - Nové API
Všetky články v sekcii
Súbory a práce s nimi v Kotlin
Preskočiť článok
(neodporúčame)
Práca s vlastnými súbormi v Kotlin - XML pre ZIP archív
Článok pre vás napísal Filip Studený
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
.
Aktivity