Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

(c) Krzysztof Barteczko 2014

Podobne prezentacje


Prezentacja na temat: "(c) Krzysztof Barteczko 2014"— Zapis prezentacji:

1 (c) Krzysztof Barteczko 2014
Klasy narzędziowe (1) (c) Krzysztof Barteczko 2014

2 Bajtowe strumienie plikowe
(c) Krzysztof Barteczko 2014

3 (c) Krzysztof Barteczko 2014
Operacje na plikach (c) Krzysztof Barteczko 2014

4 (c) Krzysztof Barteczko 2014
Przykład (c) Krzysztof Barteczko 2014

5 (c) Krzysztof Barteczko 2014
try-with-resources (c) Krzysztof Barteczko 2014

6 Pliki tekstowe i strony kodowe
Każdy plik jest sekwencją bajtów. Znaczenie bajtów może być różne - liczby, znaki. W Javie znaki są przedstawiane w Unikodzie. A pliki tekstowe zapisywane są w różnych systemach kodowania, niekoniecznie w Unicodzie. Sposób kodowania znaków tekstu nazywa się stroną kodową. Np. wiele polskich dokumentów HTML zapisanych jest z wykorzystaniem strony  kodowej ISO8859-2, inne - z wykorzystaniem strony Cp1250 (inaczej zwanej Windows 1250).  W każdym systemie operacyjnym jest ustawiona tzw. domyślna strona kodowa, która będzie wykorzystywana np. przy wczytywaniu i zapisie plików przez systemowe edytory tekstu. Np. w systemie Windows taką domyślną stroną kodową często jest - w polskich warunkach - Cp1250 lub UTF-8. Przy wczytywaniu Java musi dokonać przekodowania plików zapisanych w domyślnej stronie kodowej na Unicode, a przy zapisie wykonać operację odwrotną - przekodowania z Unicodu do domyślnej strony kodowej. Metody klas FileInputStream i FileOutputStream - nie wykonują tego zadania (czytają i piszą bajt po bajcie), co w przypadku plików tekstowych może powodować utratę informacji. (c) Krzysztof Barteczko 2014

7 (c) Krzysztof Barteczko 2014
Strumienie znakowe Strat informacji nie będzie, jeśli do czytania plików wykorzystamy obiekt klasy FileReader, a do zapisywania – FileWriter Klasy te zapewniają konwersje między domyślną stroną kodową systemu operacyjnego i  Unicodem. Te klasy reprezentuja tzw. strumienie znakowe, bo operacje czytania/zapisu dokonują przekształceń bajty <-> znaki. (c) Krzysztof Barteczko 2014

8 (c) Krzysztof Barteczko 2014
Buforowanie Operacje fizycznych odwołań do pliku (dysku) są czasochłonne. Aby je ograniczyć - stosujemy tzw. buforowanie. W pamięci operacyjnej wydzielany jest duży obszar pamięci, który zapełniany jest przez jednorazowe fizyczne odwołanie do pliku. Instrukcje czytania pliku pobierają informacje z tego bufora. Gdy bufor jest pusty - następuje kolejne jego wypełnienie poprzez fizyczne odwołanie do pliku. W ten sposób liczba fizycznych odwołań do pliku (do dysku) jest mniejsza niż liczba zapisanych w programie instrukcji czytania danych. Zapisywanie pliku „działa w odwrotną stronę”  Buforowanie czytania: BufferedReader +  wygodna metoda  readLine()  Buforowanie zapisu: BufferedWriter + wygodna metoda newLine() (c) Krzysztof Barteczko 2014

9 (c) Krzysztof Barteczko 2014
Przykład static void copyLines(String infn, String outfn) throws IOException { try (BufferedReader in = new BufferedReader(new FileReader(infn)); BufferedWriter out = new BufferedWriter(new FileWriter(outfn)) ) { String line; while ((line = in.readLine()) != null) { out.write(line); out.newLine(); } (c) Krzysztof Barteczko 2014

10 (c) Krzysztof Barteczko 2014
Przekodowanie (c) Krzysztof Barteczko 2014

11 Dla plików – lepsze narzędzia
 czytanie plików tekstowych: Scanner czytanie i pisanie dla dowolnych plików: metody klasy java.nio.Files Wymagają reprezentacji obiektów plikowych m.in. jako: File File f = new File("tekst.txt");  Path (c) Krzysztof Barteczko 2014

12 (c) Krzysztof Barteczko 2014
Scanner Scanner scan = new Scanner(new File("x.txt")); // domyślna strona kodowa (c) Krzysztof Barteczko 2014

13 Skaner – sumowanie liczb z pliku
File f = new File("nums.txt"); long sum = 0; String msg; try (Scanner sc = new Scanner(f)) { while(sc.hasNextInt()) sum += sc.nextInt(); msg = "Suma: " + sum; } catch (Exception exc) { msg = exc.toString(); } System.out.println(msg); (c) Krzysztof Barteczko 2014

14 (c) Krzysztof Barteczko 2014
Klasa java.nio.Files Wygodnie operuje się na plikach statycznymi metodami klasy Files z pakietu java.nio.file. To jest całkiem inna klasa niż klasa File, bo: zapewnia znacznie lepszą reprezentację współczesnych systemów i obiektów plikowych (m.in. większą liczbę atrybytów obiektów plikowych,  obsługę tzw. symbolicznych linków).  dostarcza prostych metod wejścia-wyjścia dla plików. Większość metod klasy Files ma argumenty typu Path. (c) Krzysztof Barteczko 2014

15 Files – kopiowanie plików
static void copyFile(String srcFn, String destFn, CopyOption ... opt) throws IOException { Path src = Paths.get(srcFn); Path dest = Paths.get(destFn); Files.copy(src, dest, opt); } public static void main(String[] args) throws IOException { copyFile("in1", "out2"); // wyjatek jesli out2 istnieje // istniejący plik out1 będzie zastąpiony copyFile("in1", "out1", REPLACE_EXISTING); // skopiowanie do katalogu Temp z zachowaniem atrybutów copyFile("in1", "/Temp/in1", COPY_ATTRIBUTES); (c) Krzysztof Barteczko 2014

16 Files – czytanie wierszy
Metoda readAllLines(...) zwraca listę wszystkich wierszy pliku, po której możemy np. iterować. Jesli nie podamy strony kodowej – UTF-8. Podanie strony kodowej pliku przy użyciu obiektu klasy Charset (domyślną stronę kodową uzyskujemy przez Charset.defaultCharset()) int lcount = 0; // liczba wierszy w pliku int llength = 0; // łaczna długość wierszy int maxLen = 0; // dlugość najdłuższego for (String line : Files.readAllLines(Paths.get("in1"), Charset.defaultCharset())) { lcount++; int len = line.length(); llength += len; if (len > maxLen) maxLen = len; System.out.println(line); } System.out.println(" "); System.out.println("Plik zawiera wierszy: " + lcount); System.out.println("O łącznej dlugości: " + llength); System.out.println("Najdłuższy wiersz ma długosć: " + maxLen); (c) Krzysztof Barteczko 2014

17 Files – czytanie i zapis bajtów
Metoda Files.getAllBytes(Path) zwraca zawartość pliku jako tablicę bajtów. Tablicę bajtów możemy zapisać do pliku, używając metody File.write(bytes[]). Metody będą użyteczne, gdy chcemy działać na plikach w postaci binarnej, ale czasem również przydadzą się do szybkiego przetwarzania plików tekstowych. Kod przedstawia zamianę w pliku znaków tabulacji na spacje. void tabsToSpaces(String fname) throws IOException { Path fpath = Paths.get(fname); byte[] cont = Files.readAllBytes(fpath); for (int i = 0; i < cont.length; i++) { if (cont[i] == 0x09) cont[i] = (byte) ' '; } Files.write(fpath, cont); Operacje readAllBytes() czy readAllLines() wykonywane są "za jednym zamachem" i zamykają pliki (tak samo operacje File.write(..)). (c) Krzysztof Barteczko 2014

18 Files – czytanie i zapis wierszy
Druga wersja metody Files.write ma jako argument listę wierszy, które mają być zapisane do pliku. Łatwo więc można zmienić kodowanie pliku. Przy okazji, do ustalania stron kodowych zastosujemy statyczną metodę forName klasy Charset. Path file = Paths.get("page.html"); Charset cpIn = Charset.forName("Cp1250"), cpOut = Charset.forName("ISO8859-2"); Files.write(file, Files.readAllLines(file, cpIn), cpOut); (c) Krzysztof Barteczko 2014

19 Wyrażenia regularne (1)
(c) Krzysztof Barteczko 2014

20 Wyrażenia regularne (2)
(c) Krzysztof Barteczko 2014

21 Wyrażenia regularne (3)
(c) Krzysztof Barteczko 2014

22 Wyrażenia regularne (4)
(c) Krzysztof Barteczko 2014

23 Do czego służą wyrażenia regularne?
(c) Krzysztof Barteczko 2014

24 (c) Krzysztof Barteczko 2014
Pattern i Matcher String regex = "..."; // wyrażenie regularne // Kompilacja wzorca Pattern pattern = Pattern.compile(regex); // Tekst wejściowy String txt = "..."; // tekst do analizy // Uzyskanie matchera Matcher matcher = pattern.matcher(txt); // ... zastosowanie metod Matchera do przetwarzania tekstu (c) Krzysztof Barteczko 2014

25 (c) Krzysztof Barteczko 2014
Metody Matchera (c) Krzysztof Barteczko 2014

26 (c) Krzysztof Barteczko 2014
Przykład 1 String regex = "[0-9]+"; String txt = " "; System.out.println("Tekst: \n" + "'" + txt + "'" "\nWzorzec: " + "'" + regex + "'"); Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(txt); String result = ""; // do prezentacji wyników wyszukiwania while (matcher.find()) { result += "\nDopasowano podłańcuch '" matcher.group() + "'" "\nod pozycji " + matcher.start() "\ndo pozycji " + matcher.end(); } if (result.equals("")) result = "Nie znaleziono żadnego podnapisu " "\npasującego do wzorca"; System.out.println(result); (c) Krzysztof Barteczko 2014

27 (c) Krzysztof Barteczko 2014
Przykład 2 String regex = "([0-9]+)\\s+(\\p{L}+)\\s+([1-9][0-9]*)"; String txt = "1111 Odkurzacz 20"; System.out.println("Tekst: " + "'" + txt + "'" "\nWzorzec: " + "'" + regex + "'"); Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(txt); boolean isMatching = matcher.matches(); if (isMatching) { int n = matcher.groupCount(); // ile grup for (int i = 1; i <=n; i++) { // pobranie zawartości i-ej grupy String grupa = matcher.group(i); System.out.println("Grupa " + i " = '" + grupa + "'"); } } else System.out.println("Tekst nie pasuje do wzorca"); (c) Krzysztof Barteczko 2014

28 (c) Krzysztof Barteczko 2014
Przykład 3 (c) Krzysztof Barteczko 2014

29 Regex w metodach klas String i Scanner
String: split, matches, replaceFirst, replaceAll. Scanner: useDelimiter(regex) zmienia regex, na którym skaner rozkłada teksty metodą next(), next(regex) zwracają kolejny symbol ograniczony  separatorami oraz pasujący do wzorca podanego w wyrażeniu regularnym i ustawiają pozycję skanera zaraz za nim, findInLine(regex) i findWithinHorizon(regex, n) wyszukują w tekście i zwracają napis pasujący do wzorca (ignorując separatory), jednocześnie przesuwając pozycję skanera za ten napis. Skaner łączy możliwość użycia wyrażeń regularnych z łatwym pobieraniem liczb (np. metoda nextInt). Należy jednak pamiętać, że przy pobieraniu liczb rzeczywistych (z separatorem miejsc dziesiętnych) skaner przyjmuje format ich zapisu (m.in. to czy separatorem miejsc dziesiętnych jest kropka czy przecinek) zgodnie z domyślną lokalizacją (aktualnymi ustawieniami regionalnymi). Używaną przez skaner lokalizację można zmienić za pomocą metody skanera useLocale(..). (c) Krzysztof Barteczko 2014

30 (c) Krzysztof Barteczko 2014
Skaner – przykład 1 (c) Krzysztof Barteczko 2014

31 (c) Krzysztof Barteczko 2014
Skaner – przykład 2 Zadanie: wyróżnić tytuły (napisy w znacznikach <h2> w dokumencie html Scanner fScan = new Scanner(new File("Dok.html")); String h2regex = "(?s)(?i)<h2>(.+?)</h2>"; while(fScan.findWithinHorizon(h2regex, 0) != null) { // Skaner może uzyskać Matcher przez odwolanie match() // Od Matchera pobierzemy zawartość jedynej grupy String title = fScan.match().group(1); System.out.println(title); } fScan.close(); (c) Krzysztof Barteczko 2014


Pobierz ppt "(c) Krzysztof Barteczko 2014"

Podobne prezentacje


Reklamy Google