Część 5.3. Operacje na plikach tekstowych
Ponieważ żaden poważniejszy program nie obejdzie się bez odwołań do plików dyskowych, to na zakończenie kursu poznamy podstawowe metody pracy z plikami tekstowymi. Java pozwala na współpracę programu z wszelkiego typu plikami i katalogami: tekstowymi i binarnymi, zapisanymi na dysku lokalnym i dostępnymi przez połączenie sieciowe. Omówienie wszystkich tych możliwości znacznie jednak przekracza zakres naszego kursu. Dlatego też omówimy jedynie pracę z lokalnymi plikami tekstowymi. Praca z plikami wymaga użycia w aplikacji klasy File, która umożliwia odwołanie do pliku. Następnie potrzebną będą klasy FileInputStream i FileOutputStream, które umożliwiają odpowiednio czytanie z i zapisywanie do pliku dyskowego. Do otwierania i zapisu pliku użyjemy obiektu klasy FileDialog, która otwiera okienko dialogowe umożliwiające wybór lokalizacji i nazwy otwieranego / zapisywanego pliku. Ponieważ każda operacja związana z plikiem dyskowym może spowodować wyjątek w programie (np.: brak pliku, który chcemy czytać, atrybut read-only dla zapisywanego pliku, itp.), to musimy wszystkie operacje dyskowe wykonywać z użyciem bloku try...catch. W tej części kursu omówimy podstawowe metody w/w klas, a następnie napiszemy program: prosty edytor tekstowy z możliwością otwarcia pliku, jego edycji w komponencie TextArea oraz zapisanie do tego samego lub nowego pliku. Klasa reprezentująca pliki i katalogi dyskowe jako abstrakt niezależny od systemu operacyjnego. Jego działanie i implementacja w konkretnym środowisku realizowane są przez maszynę wirtualną podczas pracy aplikacji. Podawanie ścieżki dostępu w zmiennych i/lub stałych powinno być zgodne ze standardem środowiska, w którym program pracuje. Dlatego bezpieczniej jest korzystać z klasy FileDialog, która jest ściśle związana z konkretnym systemem.Obiekt klasy File jest niezmienny: raz utworzony reprezentuje obiekt, który nie może podlegać jakimkolwiek zmianom.
Obiekt klasy FileInputStream służy do pobrania bajtów z danymi z pliku dyskowego. Może być użyty do odczytywania zarówno plików tekstowych, jak i binarnych (baz danych, grafiki, itp.).
Obiekt klasy FileOutputStream służy do zapisywania danych do pliku dyskowego (obiektu klasy File Jeżeli plik, do którego chcemy zapisywać dane nie może być otwarty w trybie do zapisu, to konstruktor klasy spowoduje powstanie wyjątku. Klasa może być wykorzystana do zapisu do pliku zarówno danych tekstowych, jak i binarnych (np. plików graficznych).
Obiekt klasy FileDialog służy do wyświetlenia ona dialogowego, z którego użytkownik może wybrać istniejący lub podać nazwę nowego pliku. Jest to okno modalne, co oznacza, że użytkownik nie ma możliwości powrotu do aplikacji bez wybrania pliku lub anulowania wyboru.
Na zakończenie tej części kursu program demonstrujący pracę z plikami dyskowymi. Jest to prosty edytor tekstowy pozwalający otworzyć plik, dokonać jego edycji i zapisać pod tą sama lub zmieniona nazwą. Można też zapisać nowy tekst do nowego lub już istniejącego pliku bez otwierania pliku. import java.awt.*; import java.awt.event.*; import java.io.*; public class FileEditor extends Frame implements WindowListener, ActionListener { TextArea textArea; public FileEditor() { super ( ); addWindowListener(this); setSize(800, 600); setResizable(false); setTitle("Edytor plików tekstowych"); setLayout(null); textArea = new TextArea(); textArea.setBounds(0, 40, 800, 580); this.add(textArea); MenuBar menuBar = new MenuBar(); setMenuBar(menuBar); Menu menu = new Menu("Plik"); menu.add(new MenuItem("Otwórz")); menu.add(new MenuItem("Zapisz")); menu.add(new MenuItem("-")); menu.add(new MenuItem("Zamknij")); menuBar.add(menu); menu.addActionListener(this); setVisible(true); } // metoda obsługująca wybraną opcję z menu public void actionPerformed (ActionEvent e) { String command = e.getActionCommand(); if (command.equals("Zamknij")) { System.exit(0); } else if (command.equals("Otwórz")) { String fileName = ShowFileDialog(FileDialog.LOAD); if (fileName != null) { // wywołanie metody otwarcia pliku Load(fileName); } } else if (command.equals("Zapisz")) { String fileName = ShowFileDialog(FileDialog.SAVE); if (fileName != null) { // wywołanie metody zapisu pliku Save(fileName); } } } // metoda odpowiedzialna za wyświetlanie okna wyboru pliku public String ShowFileDialog (int mode) { // tworzymy nowe okno dialogowe FileDialog fileDialog = new FileDialog(this); // ustalamy tryb odczyt / zapis fileDialog.setMode(mode); // wyświetlamy okno dialogowe fileDialog.show(); // pobieramy i zwracamy nazwę wybranego pliku String fileName = fileDialog.getFile(); return (fileName); } // wczytanie i wyświetlenie pliku public void Load (String fileName) { // tworzenie zmiennych strumienia i pliku wejściowego FileInputStream fileInput = null; File file = new File(fileName); // otwarcie pliku wejściowego: // może wystąpić wyjątek, dlatego musimy użyć bloku try...catch try { fileInput = new FileInputStream(file); } catch(FileNotFoundException e) { System.out.println("Brak pliku " + fileName); return; } textArea.setText(""); byte buffer [ ] = new byte [ (int)file.length() ]; // czytanie z pliku: // tu też może wystąpić wyjątek, dlatego używamy bloku try...catch try { fileInput.read(buffer); { textArea.append (new String(buffer)); } fileInput.close(); } catch(IOException e) { System.out.println("Bład podczas czytania pliku"); return; } // zmieniamy tytuł aplikacji setTitle("Edytor plików tekstowych [" + fileName + "]"); } // zapis tekstu do pliku na dysk public void Save (String fileName) { // tworzenie zmiennych strumienia i pliku wyjściowego FileOutputStream fileOutput = null; File file = new File(fileName); // otwarcie pliku wyjściowego: // może wystąpić wyjątek, dlatego musimy użyć bloku try...catch try { fileOutput = new FileOutputStream(file); } catch(FileNotFoundException e) { System.out.println("Błąd otwarcia do zapisu pliku " + fileName); return; } // zapis do pliku: // tu też może wystąpić wyjątek, dlatego używamy bloku try...catch try { byte buffer[] = textArea.getText().getBytes(); fileOutput.write(buffer); fileOutput.close(); } catch(IOException e) { System.out.println("Błada podczas zapisu pliku"); return; } // zmieniamy tytuł aplikacji setTitle("Edytor plików tekstowych [" + fileName + "]"); } public static void main(String args[]) { new FileEditor(); } public void windowClosing (WindowEvent e) { System.exit(0); } public void windowClosed (WindowEvent e) { } public void windowOpened (WindowEvent e) { } public void windowIconified (WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowActivated (WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } }
A tak wygląda okno programu po uruchomieniu:
|