IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

19. diel - Práca s vlastnými súbormi v Jave - Zip archív

V minulej lekcii, Práca so súbormi a priečinkami v Jave - Nové API, sme si ukázali prácu so súbormi a priečinkami v Jave.

Teraz už viete pracovať s množstvom druhov súborov, viete ich ukladať a otvárať, prehrávať, odchytávať chyby, ... Predstavte si však reálnu aplikáciu na evidenciu zamestnancov. Zamestnanec bude mať 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ú binárne súbory pomerne nešikovné a zle sa s nimi reaguje na zmeny formátu.

Archív zip

Podobné aplikácie často využívajú na ukladanie dát archívy. Vezmite si taký MS-Word a jeho dokumenty s príponou súborov .docx. Keď zmeníte príponu ľubovoľného .docx súboru na .zip, zistíte, ž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 Document.docx vidíte len Document. Nastavenie zmeníte v ovládacom paneli, tu kliknite na View > Show > File name extension.

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 .employee alebo ak sa chcete držať trojpísmenných, tak len .emp.

Prípona súboru totiž 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 .emp. Zip 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 .emp

Štruktúra zazipovanej zložky by mohla byť nasledovná:

data.emp
|-- employees.xml
|-- images/
    |-- firstnamelastname_1.png
    |-- firstnamelastname_2.png

Súbor employees.xml by mohol vyzerať nasledovne:

<employees>
    <employee>
        <firstName>Thomas</firstName>
        <lastName>Cooper</lastName>
        <email>[email protected]</email>
        <phone>123456789</phone>
        <birthdate>1/1/1970</birthdate>
    </employee>
</employees>

Element <employees> 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 Employees

Vytvorte 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 v Jave - Práca so súbormi v Jave

Trieda Employee

Začneme tým, čo by malo byť jasné - vlastnosťami. Náš zamestnanec bude mať:

  • meno,
  • priezvisko,
  • email,
  • telefón,
  • dátum narodenia
  • a bude mať aj fotografiu:
public class Employee {

    private String firstName;
    private String lastName;
    private String email;
    private String phone;
    private LocalDate birthdate;
    private BufferedImage image;

    public Employee() {
        this("", "", "", "", LocalDate.now());
    }

    public Employee(String firstName, String lastName, String email, String phone, LocalDate birthdate) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.phone = phone;
        this.birthdate = birthdate;
    }

    @Override
    public String toString() {
        return "Employee{" + "first name=" + firstName + ", last name=" + lastName + '}';
    }
}

Trieda má dva konštruktory. Prvé preťaženie vytvorí prázdneho zamestnanca. Pomocou druhého konštruktora vytvoríme inštanciu zamestnanca so všetkými údajmi, okrem obrázku.

Gettery a settery

Ďalej nasledujú iba gettery a settery pre tieto vlastnosti:

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getPhone() {
    return phone;
}

public void setPhone(String phone) {
    this.phone = phone;
}

public LocalDate getBirthdate() {
    return birthdate;
}

public void setBirthdate(LocalDate birthdate) {
    this.birthdate = birthdate;
}

public BufferedImage getImage() {
    return image;
}

public void setImage(BufferedImage image) {
    this.image = image;
}

Do formulára si pridáme premennú typu Employee, ale nebudeme ju inštancovať:

private Employee employee;

Správca zamestnancov

Aby sme dodržali oddelenie logiky a GUI, založíme si novú triedu, ktorá sa bude starať o správu zamestnancov. Triedu nazvime jednoducho EmployeeManager. Trieda bude obsahovať kolekciu zamestnancov. Kolekcia bude typu DefaultListModel, aby sme ju neskôr mohli využiť pre viacerých zamestnancov.

private final DefaultListModel<Employee> employees = new DefaultListModel<>();

Ďalej vytvoríme v triede štyri metódy: save(), load(), getFirst() a saveFirst(). Metódy save() a load() budeme implementovať až v nasledujúcej lekcii. Posledné dve metódy tu máme iba pre jednoduchosť, aby sme mohli pracovať s jedným zamestnancom. Ich implementácia bude nasledovná:

public Employee getFirst() {
    return employees.size() == 0 ? new Employee() : employees.get(0);
}

public void saveFirst(Employee employee) {
    this.employees.clear();
    this.employees.addElement(employee);
}

Úprava formulára

To by bolo zatiaľ v správcovi všetko. Presuňme sa ešte rýchlo do formulára, kde vytvoríme inštanciu správcu a necháme si od neho inštancovať triedu Employee:

private final EmployeeManager manager = new EmployeeManager();
private Employee employee = manager.getFirst();

Ďalej do kódu formulára pridáme dve pomocné metódy, pomocou ktorých budeme aktualizovať údaje na formulári a v inštancii triedy Employee:

private void refreshForm() {
    jTxtFirstName.setText(employee.getFirstName());
    jTxtLastName.setText(employee.getLastName());
    jTxtEmail.setText(employee.getEmail());
    jTxtPhoneNumber.setText(employee.getPhone());
    jTxtBirthday.setText(Constants.FORMAT_DATA.format(employee.getBirthdate()));
    jPanel1.getGraphics().drawImage(employee.getImage(), 0, 0, 123, 135, null);
}

private void loadFromForm() {
    employee.setFirstName(jTxtFirstName.getText());
    employee.setLastName(jTxtLastName.getText());
    employee.setEmail(jTxtEmail.getText());
    employee.setPhone(jTxtPhoneNumber.getText());
    employee.setBirthdate(LocalDate.parse(jTxtBirthday.getText(), Constants.FORMAT_DATA));
}

Obsluha tlačidiel

Nakoniec sa pozrieme na handlery tlačidiel.

Výber obrázku

Prvý handler, na ktorý sa zameriame, je obsluha tlačidla pre výber obrázku:

imageButton.addActionListener(new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
         JFileChooser fileChooser = new JFileChooser();
         fileChooser.setFileFilter(new FileNameExtensionFilter("Images...", "png"));
         final int result = fileChooser.showOpenDialog(form);
         if (result == JFileChooser.APPROVE_OPTION) {
             final File image = fileChooser.getSelectedFile();
             try {
                 employee.setImage(ImageIO.read(image));
                 refreshForm();
             } catch (IOException ex) {
                 ex.printStackTrace();
             }
         }
    }
});

Najskôr uložíme prípadné hodnoty z komponentov do inštancie triedy Employee. Ďalej vytvoríme nový JFileChooser dialóg, pomocou ktorého vyberieme obrázok používateľa. Pokiaľ obrázok vyberieme úspešne, metódou ImageIO.read() načítame obrázok a uložíme ho do zamestnanca. Nakoniec zavoláme metódu refreshForm(), pomocou ktorej zobrazíme obrázok na formulári.

Uloženie

Obsluha tlačidla na uloženie dát bude vyzerať nasledovne:

saveButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new FileNameExtensionFilter("Employee files...", "emp"));
        final int result = fileChooser.showSaveDialog(form);
        if (result == JFileChooser.APPROVE_OPTION) {
            final File employeeFile = fileChooser.getSelectedFile();
            try {
                loadFromForm();
                manager.saveFirst(employee);
                manager.save(employeeFile);
            } catch (IOException | XMLStreamException ex) {
                ex.printStackTrace();
            }
        }
    }
});

Pomocou JFileChooser dialógu vyberieme súbor, do ktorého chceme uložiť naše dáta. Ak súbor vyberieme, načítame dáta z formulára do inštancie zamestnanca. Túto inštanciu odovzdáme do správcu, aby si uložil dáta. Nakoniec metódou save() zapíšeme všetky dáta do súboru.

Načítanie

Nakoniec si ukážeme metódu na načítanie dát:

loadButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new FileNameExtensionFilter("Employee files...", "emp"));
        final int result = fileChooser.showOpenDialog(form);
        if (result == JFileChooser.APPROVE_OPTION) {
            final File employeeFile = fileChooser.getSelectedFile();
            try {
                manager.load(employeeFile);
                employee = manager.getFirst();
                refreshForm();
            } catch (IOException | ParserConfigurationException | SAXException ex) {
                ex.printStackTrace();
            }
        }
    }
});

V metóde opäť zobrazíme JFileChooser dialóg pre výber zamestnancov. Ak zvolíme súbor, zavoláme metódu load() nad inštanciu triedy EmployeeManager. Po úspešnom načítaní zobrazíme dáta prvého zamestnanca na formulár.

Teraz máme aplikáciu navrhnutú.

V nasledujúcom kvíze, Kvíz - Práca so súbormi a priečinkami v Jave, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.


 

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é 0x (8.72 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java

 

Predchádzajúci článok
Práca so súbormi a priečinkami v Jave - Nové API
Všetky články v sekcii
Práca so súbormi v Jave
Preskočiť článok
(neodporúčame)
Kvíz - Práca so súbormi a priečinkami v Jave
Článok pre vás napísal Petr Štechmüller
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje primárně programování v Javě, ale nebojí se ani webových technologií.
Aktivity