Edytuj stronę Odnośniki Fold/unfold all ODT export Ta strona jest tylko do odczytu. Możesz wyświetlić źródła tej strony ale nie możesz ich zmienić. ====== Operacje na plikach ====== * pliki o określonym formacie (csv, dat, PNG, mp3) - funkcje wysokopoziomowe * ''%%load%%'', ''%%save%%'' - wczytywanie i zapis zmiennych Matlaba oraz plików tekstowych o tabelarycznej strukturze * ''%%imread%%'', ''%%imwrite%%'' - pliki grficzne (PNG, JPG, …) * ''%%xlsread%%'', ''%%xlswrite%%'' - arkusze kalkulacyjne Excel * ''%%dlmread%%'', ''%%dlmwrite%%'' - pliki tektowe w tabelarycznej formie z separatorem * ''%%importdata%%'' - wiele formatów (ASCII, csv, jpg, xls, …) * pliki z nieokreśloną strukturą -> operacje I/O niskopoziomowe * ''%%fopen%%'', ''%%fprintf%%'', ''%%fscanf%%'', … ===== Funckje load i save ===== * ''%%save 'nazwa_pliku'%%'' zapisuje wszystkie zminne (całą przestrzeń roboczą) do pliku * ''%%save 'nazwa_pliku', x%%'' zapis zmiennej ''%%x%%'' do pliku * ''%%save 'nazwa_pliku' x --ascii%%'' zapis xmiennej ''%%x%%'' do pliku w postaci tekstowej <code> x = rand(3,5); % zapis do pliku save 'zmienna.mat' x; </code> <code> % odczyt z pliku z = load('zmienna'); disp(z) whos z x </code> <code> scalar structure containing the fields: x = 0.8776665 0.2506873 0.9552747 0.0312580 0.0818354 0.8777180 0.6151687 0.5800066 0.6321469 0.0067620 0.8095648 0.9337047 0.2573228 0.9117260 0.7223300 Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== z 1x1 120 struct x 3x5 120 double Total is 16 elements using 240 bytes </code> ===== Zapis w postaci tekstowej ===== <code> x = rand(3,5); save 'zmienna2.dat' x -ascii </code> <code> z = load('zmienna2.dat'); whos z type 'zmienna2.dat' </code> <code> Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== z 3x5 120 double Total is 15 elements using 120 bytes 8.51829831e-01 3.14490508e-01 7.18888325e-01 1.94464344e-01 3.19602559e-01 4.86406622e-01 4.76122682e-02 8.42678715e-01 7.68031369e-01 1.11815726e-01 5.24032888e-01 5.59926339e-01 1.65799131e-01 9.59999895e-01 7.54648133e-01 </code> ===== Odczyt obrazów ===== * ''%%imread('nazwa_pliku')%%'' odczyt pliku o podanej nazwie (JPEG, PNG, inne, …) * ''%%imfinfo('nazwa_pliku')%%'' informacje o opbrazie (np. szerokość i wysokość) * ''%%imwrite(X, 'nazwa_pliku')%%'' zapis macierzy ''%%X%%'' w postaci pliku graficznego (format okreslony rozszerzeniem) * ''%%imshow(X)%%'' wyświetla obraz zapisany w macierzy ''%%X%%'' * ''%%image(X)%%'' wyświetla zawartość macierzy w postaci obrazu (wartości mapowane sa na kolory pikseli) <code> % Plik Lenna.png można pobrać ze strony https://en.wikipedia.org/wiki/Lenna % Odczyt pliku graficznego x = imread('Lenna.png'); whos x </code> <code> Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== x 512x512x3 786432 uint8 Total is 786432 elements using 786432 bytes </code> <code> % Wyswietlenie obrazu imshow(x) </code> {{zajecia:pp2_2020_2:08_lab_files:08_lab_9_0.png| png}} <code> % Informacje o pliku graficznym info = imfinfo('Lenna.png') </code> <code> info = scalar structure containing the fields: Filename = /home/marek/work/zajecia/2020.zimowy/pp2/github/Lenna.png FileModDate = 19-Jan-2021 09:39:34 FileSize = 473831 Format = PNG FormatVersion = Width = 512 Height = 512 BitDepth = 8 ColorType = truecolor DelayTime = 0 DisposalMethod = LoopCount = 0 ByteOrder = undefined Gamma = 0.45455 Chromaticities = Columns 1 through 6: 0.312700 0.329000 0.640000 0.330000 0.300000 0.600000 Columns 7 and 8: 0.150000 0.060000 Comment = Quality = 75 Compression = undefined Colormap = [](0x0) Orientation = 1 ResolutionUnit = undefined XResolution = 0 YResolution = 0 Software = Make = Model = DateTime = ImageDescription = Artist = Copyright = DigitalCamera = scalar structure containing the fields: GPSInfo = scalar structure containing the fields: </code> <code> % Wizualiacja elementów macierzy y = rand(100, 200) * 255; image(y) </code> {{zajecia:pp2_2020_2:08_lab_files:08_lab_11_0.png| png}} <code> image(x) </code> {{zajecia:pp2_2020_2:08_lab_files:08_lab_12_0.png| png}} <code> % adres URL zamiast nazwy pliku x = imread('https://wydzialy.umk.pl/_szablony/grafika/logo5.png'); whos x image(x) </code> <code> Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== x 392x866x3 1018416 uint8 Total is 1018416 elements using 1018416 bytes </code> {{zajecia:pp2_2020_2:08_lab_files:08_lab_13_1.png| png}} <code> % Odwrócenie kolorów (negatyw) y = 255 - x; image(y(:,:,1)); </code> {{zajecia:pp2_2020_2:08_lab_files:08_lab_14_0.png| png}} <code> % zapis macierzy w pliku graficznym imwrite(y(1:200,1:200,1), 'logo.bmp'); imfinfo('logo.bmp') </code> <code> ans = scalar structure containing the fields: Filename = /home/marek/work/zajecia/2020.zimowy/pp2/github/logo.bmp FileModDate = 21-Jan-2021 23:17:59 FileSize = 120054 Format = BMP FormatVersion = Width = 200 Height = 200 BitDepth = 8 ColorType = grayscale DelayTime = 0 DisposalMethod = LoopCount = 0 ByteOrder = undefined Gamma = 0 Chromaticities = [](1x0) Comment = Quality = 75 Compression = undefined Colormap = [](0x0) Orientation = 1 ResolutionUnit = Centimeter XResolution = 29.250 YResolution = 29.250 Software = Make = Model = DateTime = ImageDescription = Artist = Copyright = DigitalCamera = scalar structure containing the fields: GPSInfo = scalar structure containing the fields: </code> <code> % podgląd zapisanego pliku x = imread('logo.bmp'); image(x) </code> {{.:08_lab_files:08_lab_16_0.png| png}} ===== Niskopoziomowe operacje na plikach ===== Podstawowe kroki postepowania: - Otworzenie pliku -> uzyskujemy deskryptor pliku - Operacje na pliku przy użyciu deskryptora: odczyt sekwencji danych, zapis, … - Zamknięcie pliku ===== Otwieranie i zamykanie plików ===== * ''%%fopen( 'nazwa', 'tryb' )%%'' otwiera plik o podanej nazwie. W przypadku niepowodzenia funkcja zwraca wartość ''%%-1%%''.\\ * Tryb otworzenia pliku: * ''%%'r'%%'' odczyt (domyślna wartość) * ''%%'w'%%'' zapis (poprzednia zawartość pliku zostaje skasowana) * ''%%'a'%%'' dodawanie zawartości na końcu instniejącego pliku * ''%%fclose(fid)%%'' zamyka plik wskazany deskryptorem ''%%fid%%'' * ''%%fclose('all')%%'' zamyka wszystkie otworzone pliki <code> fid = fopen('plik.txt', 'r'); if fid == -1 disp('Problem z otworzeniem pliku') else disp('OK. Otworzyłem plik') fclose(fid) end </code> <code> Problem z otworzeniem pliku </code> ===== Operacje odczytu z pliku ===== * ''%%fscanf(fid, 'format')%%'' wczytuje dane do macierzy zgodnie z zadanym formatem\\ * Format: * ''%%%f%%'' double, liczby rzeczywiste, * ''%%%d%%'' int, liczby całkowite, * ''%%%s%%'' napis, * ''%%%c%%'' znak. * ''%%textscan(fid, 'format')%%'' wczytuje dane do macierzy komórkowej zgodnie z podanym formatem * ''%%fgets(fid)%%'', ''%%fgetl(fid)%%'' wczytują linię tekstu z pliku * ''%%feof(fid)%%'' czy koniec pliku? ===== fscanf ===== * ''%%fscan(fid, 'format')%%'' wczytuje do macierzy wartości dopóki format jest zgodny lub do kóóńca pliku * jeśli wynikiem jest macierz liczb to ewentualne znaki zamieniane są na wartości kodu ASCII * ''%%%f%%'' i ''%%%d%%'' czyta kolejne liczby oddzielone białymi znakami (spacjami) * ''%%%c%%'' czyta dowolny znak (także spacje) <code> type 'plik1.dat' </code> <code> fid = fopen('plik1.dat'); if fid ~= -1 a = fscanf(fid, '%f'); fclose(fid); end disp(a) whos a </code> <code> 42.300 Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 1x1 8 double Total is 1 element using 8 bytes </code> <code> fid = fopen('plik1.dat'); if fid ~= -1 a = fscanf(fid, '%f %c'); fclose(fid); end disp(a) disp(char(a(2))) % druga wartość to znak A whos a </code> <code> 42.300 65.000 A Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 2x1 16 double Total is 2 elements using 16 bytes </code> <code> fid = fopen('plik1.dat'); if fid ~= -1 a = fscanf(fid, '%c'); fclose(fid); end % wszystkie znaki wczytane do wektora kolumnowego disp(a) whos a </code> <code> 42.3 Anna 32.1 Jan 13.2 Janusz 5.4 Julia 3.3 Kacper Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 1x57 57 char Total is 57 elements using 57 bytes </code> Okreslenie rozmiaru macierzy wyjściowej (liczby wczytanych wartości)\\ ''%%fscanf(fid, 'format', rozmiar)%%'' * rozmiar ''%%N%%'' wczyta okresloną liczbę wartości * rozmiar ''%%[N M]%%'' wczyta ''%%NxM%%'' wartości do macierzy * rozmiar ''%%[N Inf]%%'' wczyta wszystkie wartości do macierzy o ''%%N%%'' wierszach <code> fid = fopen('plik1.dat'); if fid ~= -1 a=fscanf(fid, '%f %s\n', [5 Inf]); fclose(fid); end disp(a) % dane umieszczane w kolejnych kolumnach disp(char(a(:, 1))) whos a </code> <code> 42.30000 32.10000 74.00000 122.00000 105.00000 99.00000 65.00000 74.00000 97.00000 5.40000 97.00000 112.00000 110.00000 97.00000 110.00000 74.00000 3.30000 101.00000 110.00000 110.00000 117.00000 117.00000 75.00000 114.00000 97.00000 13.20000 115.00000 108.00000 97.00000 0.00000 * A n n a Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== a 5x6 240 double Total is 30 elements using 240 bytes </code> **Ćwiczenie** wyznacz sumę wartośći zawartą w pierwszej kilumnie pliku ‘plik1.dat’ ===== fgetl() ===== * ''%%fgetl(fid)%%'' wczytuje linię z pliku (bez znaku nowej linii) * ''%%fgets(fid)%%'' wczytuje linię z pliku (ze znakiem nowej linii) <code> fid = fopen('plik1.dat'); y = 0 if fid ~= -1 while feof(fid) == 0 linia = fgetl(fid); [x s] = strtok(linia); fprintf('x=%f s=%s\n', str2num(x), s); y = y + str2num(x); end fclose(fid); end disp(y) </code> <code> y = 0 x=42.300000 s= Anna x=32.100000 s= Jan x=13.200000 s= Janusz x=5.400000 s= Julia x=3.300000 s= Kacper 96.300 </code> **Ćwiczenie** wyznacz sumę wartośći zawartą w pierwszej kilumnie pliku ‘plik1.dat’ czytając dane za pomocą ''%%fgetl%%'' ===== textscan ===== * ''%%textscan(fid, format)%%'' wczytuje dane do macierzy komórkowej * ''%%format%%'' analogicznie jak w ''%%printf%%'', np,: ''%%"%f %s"%%'' okresla liczbę double i następujący po spacji napis <code> fid = fopen('plik1.dat'); if fid ~= -1 x = textscan(fid, '%f %s'); fclose(fid); end a = x{1} b = x{2} whos x a b </code> <code> a = 42.3000 32.1000 13.2000 5.4000 3.3000 b = { [1,1] = Anna [2,1] = Jan [3,1] = Janusz [4,1] = Julia [5,1] = Kacper } Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== x 1x2 64 cell a 5x1 40 double b 5x1 24 cell Total is 12 elements using 128 bytes </code> <code> fid = fopen('plik1.dat'); if fid ~= -1 x = textscan(fid, '%c'); fclose(fid); end whos x x </code> <code> Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== x 1x1 43 cell Total is 1 element using 43 bytes x = { [1,1] = { [1,1] = 4 [2,1] = 2 [3,1] = . [4,1] = 3 [5,1] = A [6,1] = n [7,1] = n [8,1] = a [9,1] = 3 [10,1] = 2 [11,1] = . [12,1] = 1 [13,1] = J [14,1] = a [15,1] = n [16,1] = 1 [17,1] = 3 [18,1] = . [19,1] = 2 [20,1] = J [21,1] = a [22,1] = n [23,1] = u [24,1] = s [25,1] = z [26,1] = 5 [27,1] = . [28,1] = 4 [29,1] = J [30,1] = u [31,1] = l [32,1] = i [33,1] = a [34,1] = 3 [35,1] = . [36,1] = 3 [37,1] = K [38,1] = a [39,1] = c [40,1] = p [41,1] = e [42,1] = r [43,1] = } } </code> <code> fid = fopen('plik1.dat'); if fid ~= -1 x = textscan(fid, '%s'); fclose(fid); end whos x x </code> <code> Variables in the current scope: Attr Name Size Bytes Class ==== ==== ==== ===== ===== x 1x1 42 cell Total is 1 element using 42 bytes x = { [1,1] = { [1,1] = 42.3 [2,1] = Anna [3,1] = 32.1 [4,1] = Jan [5,1] = 13.2 [6,1] = Janusz [7,1] = 5.4 [8,1] = Julia [9,1] = 3.3 [10,1] = Kacper } } </code> **Ćwiczenie** wyznacz sumę wartości w pierwszej kolumnie pliku za pomocą ''%%textscan%%'' ===== Zapisywanie danych do pliku ===== * ''%%fprintf(fid, 'format', arg, ... )%%'' zapisuje dane w podanym formacie * argumentem może być wartość skalarna ale też i cała macierz <code> fid = fopen('output.dat', 'w'); if fid ~= -1 fprintf(fid, 'Witaj Świecie\n'); for i=1:10 fprintf(fid, '%d do potęgi 2 wynosi %f\n', i, i^2); end fclose(fid); end </code> <code> type 'output.dat' </code> <code> Witaj Świecie 1 do potęgi 2 wynosi 1.000000 2 do potęgi 2 wynosi 4.000000 3 do potęgi 2 wynosi 9.000000 4 do potęgi 2 wynosi 16.000000 5 do potęgi 2 wynosi 25.000000 6 do potęgi 2 wynosi 36.000000 7 do potęgi 2 wynosi 49.000000 8 do potęgi 2 wynosi 64.000000 9 do potęgi 2 wynosi 81.000000 10 do potęgi 2 wynosi 100.000000 </code> ===== Zapis macierzy ===== <code> x = rand(5, 3) fid = fopen('macierz1.dat', 'w'); if fid ~= -1 fprintf(fid, '%f\n', x); fclose(fid); end </code> <code> x = 0.648652 0.058833 0.349327 0.768758 0.020663 0.141534 0.996369 0.347898 0.868106 0.377173 0.702610 0.584028 0.373202 0.469776 0.851421 </code> <code> type 'macierz1.dat' </code> <code> 0.648652 0.768758 0.996369 0.377173 0.373202 0.058833 0.020663 0.347898 0.702610 0.469776 0.349327 0.141534 0.868106 0.584028 0.851421 </code> <code> x = rand(5, 3) fid = fopen('macierz2.dat', 'w'); if fid ~= -1 fprintf(fid, '%f %f %f\n', x); fclose(fid); end </code> <code> x = 0.9933395 0.8791829 0.9703252 0.0179931 0.0372486 0.3797892 0.5577293 0.6500757 0.0090017 0.1238437 0.7979600 0.8138178 0.7468451 0.1667082 0.4569186 </code> <code> % elementy zapisane w kolejności kolumnowej type 'macierz2.dat' </code> <code> 0.993339 0.017993 0.557729 0.123844 0.746845 0.879183 0.037249 0.650076 0.797960 0.166708 0.970325 0.379789 0.009002 0.813818 0.456919 </code> ===== Dodawanie zawartości do pliku ===== <code> type 'output.dat' </code> <code> Witaj Świecie 1 do potęgi 2 wynosi 1.000000 2 do potęgi 2 wynosi 4.000000 3 do potęgi 2 wynosi 9.000000 4 do potęgi 2 wynosi 16.000000 5 do potęgi 2 wynosi 25.000000 6 do potęgi 2 wynosi 36.000000 7 do potęgi 2 wynosi 49.000000 8 do potęgi 2 wynosi 64.000000 9 do potęgi 2 wynosi 81.000000 10 do potęgi 2 wynosi 100.000000 </code> <code> fid = fopen('output.dat', 'a'); if fid ~= -1 fprintf(fid, 'Dopisek: %s\n', date); fclose(fid); end type 'output.dat' </code> <code> Witaj Świecie 1 do potęgi 2 wynosi 1.000000 2 do potęgi 2 wynosi 4.000000 3 do potęgi 2 wynosi 9.000000 4 do potęgi 2 wynosi 16.000000 5 do potęgi 2 wynosi 25.000000 6 do potęgi 2 wynosi 36.000000 7 do potęgi 2 wynosi 49.000000 8 do potęgi 2 wynosi 64.000000 9 do potęgi 2 wynosi 81.000000 10 do potęgi 2 wynosi 100.000000 Dopisek: 21-Jan-2021 </code> ===== Zadanie 9. Szyfrowanie pliku ===== Stwórz plik o nazwie ''%%szyfr.m%%'' a w nim zdefiniuj funkcję o nazwe ''%%szyfr()%%'', która zaszyfruje zawartość pliku za pomocą algorytmu szyfrowania macierzowego. **Działanie szyfrowania macierzowego:** szyfrowany tekst umiszczamy w macierzy o liczbie kolumn K. Teskt umiszczany jest w kolejnych wierszach. Przykładowo, tekst ''%%tajna wiadomość%%'' umieszczony w macierzy o 5 kolumnach wypełni 3 wiersze (ewentualne brakujące elementy w ostatnim wierszu wypełniamy spacjami): <code> tajna wiad omość </code> Metoda polega na odczytaniu tekstu uzyskanego w kolumnach, czyli w tym przypadku wynikiem będzie: ''%%t oawmjionaśadć%%''. Ilość wierszy macierzy szyfrującej staje się kluczem pozwalającym odszyfrować wiadomość. Proces ten przebiega analogicznie, tzn. umieszczamy zaszyfrowany tekst w macierzy o 3 kolumnach (tyle wierszy miała macierz szyfrująca) i odczytujemy treść uzyskaną w kolumnach. <code> t o awm jio naś adć </code> Funkcja ''%%szyfr()%%'' przyjmuje 3 argumenty: nazwę pliku wejściowego, nazwę pliku wyjściowego oraz liczbę całkowitą okreslającą ilość kolumn macierzy szyfrującej. Funkcja zwraca liczbę całkowitą równą liczbie wierszy macierzy szyfrującej.\\ Przykładowo: <code> x = szyfr('plik.txt', 'tajne.txt', 42); </code> zaszyfruje zawartość pliku ''%%plik.txt%%'' za pomocą macierzy posiadającej 42 kolumny i zaszyfrowaną treść umieści w pliku ''%%tajne.txt%%''. Do zmiennej ''%%x%%'' zostanie podstawiowna liczba wierszy macierzy szyfrującej. Ta wartość stanowi klucz, który jest niezbędny do odszyfrowania wiadomości, tzn.: <code> szyfr('tajne.txt', 'odszyfrowane.txt', x); </code> umieści w pliku ''%%odszyfrowane.txt%%'' oryginalną, rozszyfrowaną treść pliku ''%%plik.txt%%''. Dwa pierwsze argumenty funkcji ''%%szyfr%%'' (nazwy plików) są obowiązkowe. W przypadku, gdy uzytkonik nie poda trzeciego argumentu wówczas liczba kolumn macierzy szyfrującej bedzie równa wartości $\sqrt{N}$ zaokrąglonej do liczby całkowitej, gdzie $N$ jest ilością wszystkich znaków w wiadomości do zaszyfrowania. W przypadku, gdy plik podany w pierszym argumencie nie istnieje, funkcja wyświetla stosowany komunikat błedu i skrypt kończy działanie. Uwaga: wystarczające jest aby prpgram obsługiwal poprawnie znaki z kodu ASCII.