Czytanie, pisanie i rysowanie – cd.
Jeszcze jeden strumyk PrintStream działa jak PrintWriter, ale: Używa domyślnego (systemowego) kodowania Nie wyrzuca wyjątków poza konstruktorami –ustawia tylko flagę, którą można sprawdzić metodą checkError() Można konstruować z OutputStream (ustawiając ew. autoFlush) lub bezpośrednio z nazwy pliku lub pliku Udostępnia –print|println(int|long|float|double|String) –printf(format,…)
I jedna metoda: W każdej klasie możemy na(d)pisać metodę String toString() Będzie ona używana przy rzutowaniu obiektu naszej klasy na String (niespodzianka: takie rzutowanie jest zawsze dozwolone!)
Przykład toString() public class Point { protected int dimension = 0; protected float[] coordinates = null;... public String toString() { if (coordinates==null) return "()"; else { StringBuffer b = new StringBuffer("("); for (int i=0; i<coordinates.length; i++) { b.append(""+ coordinates[i]); if (i<coordinates.length-1) b.append(","); } return b+")"; }
I możemy teraz drukować punkty float[] a = {"1,2,3"}; Point p = new Point(a); println(""+p); Point2D oczywiście odziedziczy tę metodę. Przy okazji:....split("(|,|)") Potnie wynik toString na elementy tablicy coordinates do wczytania przez Float.parseFloat()
Object...Stream i serializacja Obiekt może być serializowalny : class Point implements Serializable Typy proste są serializowalne z natury, podobnie jak tablice, kontenery, typ String i inne (sprawdzamy w Javadoc, czy dany typ implements Serializable) Własnym klasom implementujemy Serializable sami (zwykle trywialnie) pamiętając, że serializacja jest głęboka – logiczne! Można pominąć serializację pola prefiksując je słowem transient
Serializacja – cd. Serializację można zaimplementować samodzielnie pisząc metody private void writeObject(java.io.ObjectOutputStream out) throws IOException private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException; private void readObjectNoData() throws ObjectStreamException; Można przy tym wołać in.defaultReadObject() i out.defaultWriteObject() A potem np. odtwarzać pola transient
Ostrożnie, obiekt serializowany! Problem: automatyczne pisanie sygnatury long serialVersionUID sprawdzanej przy deserializacji. Obejście serialVersionUID można nadpisać, np.: private static final long serialVersionUID = 1L; serialver class zwraca automatyczną wartość serialVersionUID - polecane serialVersionUID zmieniamy, gdy: Zmieniły się serializowane (nie transient) pola – zawsze Istotnie zmieniła się klasa – według uznania
Object...Stream – cd. Mając obiekt klasy serializable możemy go zapisać: Point pt =.... ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(fileName)); out.writeObject(pt); I odczytać ObjectInputStream in = new ObjectInputStream( new FileInputStream(fileName)); Point pt = in.ReadObject(); Lub przesłać przez sieć i mieć pewność, że zostanie prawidłowo odczytany...
GUI czytania i pisania: // Budujemy okienko katalogu private JFileChooser fileChooser = new JFileChooser(); private FileFilter filter = new FileNameExtensionFilter("JPEG file","jpg","jpeg"); fileChooser.addFileFilter(filter); // I uaktywniamy je po naciśnięciu przycisku saveButton : private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) { int returnVal = dynChooser.showOpenDialog(null); // Użytkownik wybrał plik if (returnVal == JFileChooser.APPROVE_OPTION) try { // więc otwieramy zgodnie z potrzebami DataOutputStream out = new DataOutputStream( new FileOutputStream( dynChooser.getSelectedFile())); // lub PrintStream printout = new PrintStream( dynChooser.getSelectedFile()));......