[Java File] Obsługa plików, zapis, odczyt💾📜 Java IO, Java NIO, FileWriter, BufferedWriter

Java file, obsługa plików

Obsługa plików w Javie nie musi być skomplikowana. Niezależnie od tego, czy piszesz swoją pierwszą aplikację, czy też szlifujesz umiejętności w zaawansowanych projektach, dzisiejsza podróż pozwoli Ci odkryć, jak w prosty sposób zapisać swoje myśli lub wyniki pracy do pliku i jak z niecierpliwością odzyskać je, kiedy tylko zamarzysz.

Obsługa plików – wprowadzenie

Z tego materiału dowiesz się:

  • Czym jest obsługa plików?
  • Jakie są biblioteki do obsługi plików?
  • Jak zapisywać dane do pliku?
  • Jak odczytywać dane z pliku?
  • Jakie są dobre praktyki podczas obsługi plików?

Obsługa plików – Pierwszy krok do panowania nad danymi

Zanim zagłębimy się w konkretne techniki, ważne jest, aby zrozumieć, czym jest plik z perspektywy programisty. Plik to po prostu zbiór danych przechowywanych na dysku, z którymi można „kontaktować się” za pomocą programu. W Javie mamy do dyspozycji kilka API, które umożliwiają te interakcje, zarówno w sposób prosty, jak i zaawansowany.

Pliki są wszędzie – przechowują nasze zdjęcia, dokumenty, muzykę i niezliczone inne rodzaje danych. W programowaniu, zarządzanie plikami pozwala nam na zapisywanie wyników, czytanie danych wejściowych, konfigurację aplikacji i wiele więcej. Java oferuje bogaty zestaw narzędzi do efektywnej pracy z plikami, pozwalając na łatwe odczytywanie, zapisywanie i manipulowanie danymi.

Obsługa plików – Java IO

Java IO (Input/Output) to tradycyjny sposób obsługi plików w Javie, oferujący klasy takie jak File, FileReader, FileWriter, BufferedReader, i BufferedWriter. Umożliwiają one operacje na plikach takie jak tworzenie, odczyt, zapis i modyfikacja.

IO

Nowoczesne podejście – Java NIO

Java New IO (NIO) to nowsza biblioteka zaprojektowana dla bardziej efektywnej pracy. Klasy Files wraz z Paths stanowią potężne narzędzie do operacji na plikach.

NIO

Zapis do pliku z użyciem FileWriter

Rozpoczniemy od klasy FileWriter, która jest jak pierwszy przyjaciel każdego programisty w Javie, kiedy przychodzi do zapisu danych.

    static void fileWriterMethod() {
        String data = "Witaj, świecie plików!";
        try (FileWriter fileWriter = new FileWriter("plik.txt")) {
            fileWriter.write(data);
            System.out.println("Pomyślnie zapisano dane.");
        } catch (IOException e) {
            System.out.println("Wystąpił błąd.");
            e.printStackTrace();
        }
    }

Zapis do pliku z użyciem PrintWriter

Dla prostych zadań, klasa PrintWriter jest Twoim najlepszym przyjacielem. Pozwala na zapisywanie tekstu do pliku w łatwy sposób.

PrintWriter jest specjalizowaną klasą do zapisu tekstu w sposób wygodny i elastyczny.

    static void printWriterMethod() {
        String data = "Witaj, to jest wygodny PrintWriter!";
        try (PrintWriter out = new PrintWriter("plikPrinter.txt")) {
            out.println(data);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

Zapis do pliku z użyciem BufferedWriter

Klasa FileWriter służy do zapisywania znaków w pliku. Aby zapewnić większą wydajność, warto użyć BufferedWriter, który dodaje buforowanie, minimalizując liczbę operacji wejścia/wyjścia.

Jeśli zależy Ci na wydajności, BufferedWriter będzie Twoim wyborem. Dzięki buforowaniu operacji, zapis przebiega szybciej, co ma znaczenie przy dużych ilościach danych.

    static void bufferedWriterMethod() {
        String data = "To jest test BufferedWriter.\nKolejna linia.";
        try (BufferedWriter writer = new BufferedWriter(new FileWriter("plikBuffer.txt"))) {
            writer.write(data);
            System.out.println("Pomyślnie zapisano dane.");
        } catch (IOException e) {
            System.out.println("Wystąpił błąd podczas zapisu.");
            e.printStackTrace();
        }
    }

Zapis plików z użyciem NIO

To podejście umożliwia np. odczyt i zapis plików za pomocą jednej linijki kodu!

    static void writeFromNIO() {
        String data = "Witaj, NIO!";
        try {
            Files.write(Paths.get("plikNIO.txt"), data.getBytes());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

Zapisywanie plików binarnych

Aby zapisać plik binarny w Javie, możesz użyć FileOutputStream, który jest przeznaczony do zapisywania bajtów do pliku. Poniżej znajdziesz przykład, jak użyć FileOutputStream do zapisania danych binarnych:

    static void filesOutputStreamWriterMethod() {
        String filePath = "plik.bin";
        byte[] data = {65, 66, 67, 68}; // Przykładowe dane w formacie binarnym

        try (FileOutputStream fos = new FileOutputStream(filePath)) {
            fos.write(data);
            System.out.println("Plik binarny został zapisany.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

➡ ZOBACZ 👉: System dwójkowy 0️⃣1️⃣ Binarna reprezentacja liczb | System Binarny 🆚 Dwójkowy

Zapisywanie obiektów (Serializacja)

Java umożliwia zapisywanie obiektów do plików za pomocą mechanizmu serializacji. Aby obiekt mógł być serializowany, klasa musi implementować interfejs Serializable. Następnie, możesz użyć ObjectOutputStream w połączeniu z FileOutputStream do zapisania obiektu do pliku.

    static void objectOutputStreamMethod() {
        User user = new User("Jan Kowalski", "tajneHaslo123");
        String filePath = "uzytkownik.ser";

        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath))) {
            oos.writeObject(user);
            System.out.println("Obiekt został zapisany.");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

W powyższym przykładzie, pole password jest oznaczone jako transient, co oznacza, że nie zostanie zapisane podczas serializacji. Jest to ważne ze względów bezpieczeństwa, gdyż nie chcemy, aby wrażliwe dane były łatwo dostępne.

Aby ten kod zadziałał, klasa User musi implementować interfejs Serializable.

import java.io.Serial;
import java.io.Serializable;


class User implements Serializable {

    @Serial
    private static final long serialVersionUID = 122344L;

    private final String name;
    private final transient String password;

    public User(String name, String password) {
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }
}

Pamiętaj, że serializacja obiektów Java jest użyteczna, ale wymaga ostrożności, zwłaszcza w kontekście bezpieczeństwa i zarządzania wersjami obiektów. Warto również rozważyć alternatywne formaty zapisu, takie jak JSON czy XML, które mogą oferować większą elastyczność i interoperacyjność.

Odczyt z pliku z użyciem FileReader

FileReader jest tak samo prosty w obsłudze, jak jego kolega do zapisu.

    static String fileReaderMethod() {
        StringBuilder content = new StringBuilder();
        try (FileReader fileReader = new FileReader("plik.txt")) {
            int i;
            while ((i = fileReader.read()) != -1) {
                content.append((char) i);
            }
        } catch (IOException e) {
            System.out.println("Wystąpił błąd podczas odczytu.");
            e.printStackTrace();
        }
        return content.toString();
    }

Odczyt z pliku z użyciem BufferedReader

Czytanie plików w Javie jest prostsze, niż mogłoby się wydawać. Używając klasy FileReader w połączeniu z BufferedReader, możesz łatwo przeczytać zawartość pliku tekstowego linia po linii. Dlaczego BufferedReader? Ponieważ zapewnia on efektywne czytanie znaków, tablic i linii.

    static List<String> bufferedReader() {
        List<String> lines = new ArrayList<>();
        try (BufferedReader br = new BufferedReader(new FileReader("plikBuffer.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                lines.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return lines;
    }

Odczyt z pliku z użyciem NIO

Bliźniacze rozwiązanie z wykorzystaniem NIO jak przy zapisie plików.

    static List<String> readFromNIO() {
        try {
            return Files.readAllLines(Paths.get("plikNIO.txt"));
        } catch (IOException e) {
            throw new RuntimeException("Wystąpił błąd podczas odczytu pliku NIO.", e);
        }
    }

Odczytywanie plików binarnych

Aby odczytać plik binarny w Javie, możesz użyć FileInputStream, który pozwala na odczytywanie danych z pliku jako strumienia bajtów. Oto przykład, jak użyć FileInputStream do odczytu danych binarnych:

    static byte[] fileInputStreamReadMethod() {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        String filePath = "plik.bin";

        try (FileInputStream fis = new FileInputStream(filePath)) {
            int singleByte;
            while ((singleByte = fis.read()) != -1) {
                buffer.write(singleByte);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer.toByteArray();
    }

W tym przykładzie, metoda read() klasy FileInputStream zwraca kolejne bajty danych aż do osiągnięcia końca pliku, oznaczonego przez wartość -1.

Odczytywanie obiektów z pliku (Deserializacja)

Aby odczytać zapisane wcześniej obiekty, użyj ObjectInputStream w połączeniu z FileInputStream. To pozwoli zrekonstruować obiekty z ich binarnej postaci z powrotem do życia w Twoim programie.

Deserializacja to proces odwrotny do serializacji, który pozwala na odtworzenie obiektu Java z jego zapisanej formy binarnej. Aby deserializować obiekt, musisz użyć ObjectInputStream w połączeniu z FileInputStream. Poniżej znajduje się przykład, jak deserializować obiekt:

    static User objectInputStreamReadMethod() {
        String filePath = "uzytkownik.ser";

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath))) {
            return (User) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

Używamy tutaj tej samej klasy User implementującej interfejs Serializable. Ponadto, należy pamiętać o obsłudze wyjątku ClassNotFoundException, który może zostać rzucony, jeśli klasa obiektu, który próbujemy deserializować, nie jest dostępna.

Deserializacja obiektów wymaga ostrożności, szczególnie jeśli źródło pliku nie jest zaufane, ponieważ może to prowadzić do ataków i innych zagrożeń bezpieczeństwa. Zawsze upewnij się, że deserializujesz dane z zaufanych źródeł i odpowiednio obsługujesz wyjątki oraz błędy.

W obu przypadkach odczytywanie plików binarnych i deserializacja obiektów kluczowe jest prawidłowe zarządzanie zasobami i obsługa wyjątków, aby zapewnić bezpieczne i efektywne działanie aplikacji.

Obsługa plików – praktyczne zastosowania

Obsługa plików to nie tylko teoria. Wyobraź sobie, że tworzysz aplikację dziennika, która zapisuje Twoje myśli każdego dnia w osobnym pliku. Lub aplikację do zarządzania budżetem, która odczytuje transakcje z zapisanych plików CSV. Możliwości są nieograniczone!

Obsługa plików – bezpieczeństwo i wydajność

Podczas pracy z plikami, ważne jest, aby pamiętać o obsłudze wyjątków i zasobach systemowych. Zawsze używaj bloków try-with-resources do automatycznego zamykania strumieni i unikaj wycieków pamięci. Ponadto pamiętaj o sprawdzaniu uprawnień do plików i zastanów się nad zastosowaniem szyfrowania dla wrażliwych danych.

Obsługa plików – najlepsze praktyki i pułapki

Pamiętaj o odpowiednim zarządzaniu zasobami – zawsze zamykaj strumienie po ich użyciu. Używaj bloków try-with-resources dla automatycznego zarządzania zasobami. Bądź świadomy wydajności – dla dużych plików rozważ użycie buforowanego odczytu i zapisu.

Asynchroniczna obsługa plików

Java NIO (New Input/Output) wprowadza AsynchronousFileChannel, pozwalając na nieblokujący odczyt i zapis do pliku. To idealne rozwiązanie, gdy chcesz zachować responsywność Twojej aplikacji.

Obsługa plików – podsumowanie

Przez naszą podróż po obsłudze plików w Javie, zagłębiliśmy się w różnorodne aspekty zapisu, odczytu oraz zarządzania danymi plikowymi – fundamentalne umiejętności każdego programisty Javy. Zaczynając od podstawowych operacji I/O, przez zastosowanie strumieni, aż po zaawansowane techniki serializacji, naszym celem było zbudowanie solidnych podstaw oraz zrozumienie najlepszych praktyk. Opanowanie tych umiejętności z pewnością otwiera nowe możliwości.


20+ BONUSOWYCH materiałów z programowania

e-book – „8 rzeczy, które musisz wiedzieć, żeby dostać pracę jako programista”,
e-book – „Java Cheat Sheet”,
checklista – „Pytania rekrutacyjne”
i wiele, wiele wiecej!

Jak zostać programistą

No comments
Share:

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *