====== 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
x = rand(3,5);
% zapis do pliku
save 'zmienna.mat' x;
% odczyt z pliku
z = load('zmienna');
disp(z)
whos z x
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
===== Zapis w postaci tekstowej =====
x = rand(3,5);
save 'zmienna2.dat' x -ascii
z = load('zmienna2.dat');
whos z
type 'zmienna2.dat'
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
===== 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)
% Plik Lenna.png można pobrać ze strony https://en.wikipedia.org/wiki/Lenna
% Odczyt pliku graficznego
x = imread('Lenna.png');
whos x
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
x 512x512x3 786432 uint8
Total is 786432 elements using 786432 bytes
% Wyswietlenie obrazu
imshow(x)
{{zajecia:pp2_2020_2:08_lab_files:08_lab_9_0.png| png}}
% Informacje o pliku graficznym
info = imfinfo('Lenna.png')
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:
% Wizualiacja elementów macierzy
y = rand(100, 200) * 255;
image(y)
{{zajecia:pp2_2020_2:08_lab_files:08_lab_11_0.png| png}}
image(x)
{{zajecia:pp2_2020_2:08_lab_files:08_lab_12_0.png| png}}
% adres URL zamiast nazwy pliku
x = imread('https://wydzialy.umk.pl/_szablony/grafika/logo5.png');
whos x
image(x)
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
x 392x866x3 1018416 uint8
Total is 1018416 elements using 1018416 bytes
{{zajecia:pp2_2020_2:08_lab_files:08_lab_13_1.png| png}}
% Odwrócenie kolorów (negatyw)
y = 255 - x;
image(y(:,:,1));
{{zajecia:pp2_2020_2:08_lab_files:08_lab_14_0.png| png}}
% zapis macierzy w pliku graficznym
imwrite(y(1:200,1:200,1), 'logo.bmp');
imfinfo('logo.bmp')
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:
% podgląd zapisanego pliku
x = imread('logo.bmp');
image(x)
{{.: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
fid = fopen('plik.txt', 'r');
if fid == -1
disp('Problem z otworzeniem pliku')
else
disp('OK. Otworzyłem plik')
fclose(fid)
end
Problem z otworzeniem pliku
===== 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)
type 'plik1.dat'
fid = fopen('plik1.dat');
if fid ~= -1
a = fscanf(fid, '%f');
fclose(fid);
end
disp(a)
whos a
42.300
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
a 1x1 8 double
Total is 1 element using 8 bytes
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
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
fid = fopen('plik1.dat');
if fid ~= -1
a = fscanf(fid, '%c');
fclose(fid);
end
% wszystkie znaki wczytane do wektora kolumnowego
disp(a)
whos a
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
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
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
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
**Ć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)
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)
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
**Ć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
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
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
fid = fopen('plik1.dat');
if fid ~= -1
x = textscan(fid, '%c');
fclose(fid);
end
whos x
x
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] =
}
}
fid = fopen('plik1.dat');
if fid ~= -1
x = textscan(fid, '%s');
fclose(fid);
end
whos x
x
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
}
}
**Ć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
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
type 'output.dat'
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
===== Zapis macierzy =====
x = rand(5, 3)
fid = fopen('macierz1.dat', 'w');
if fid ~= -1
fprintf(fid, '%f\n', x);
fclose(fid);
end
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
type 'macierz1.dat'
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
x = rand(5, 3)
fid = fopen('macierz2.dat', 'w');
if fid ~= -1
fprintf(fid, '%f %f %f\n', x);
fclose(fid);
end
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
% elementy zapisane w kolejności kolumnowej
type 'macierz2.dat'
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
===== Dodawanie zawartości do pliku =====
type 'output.dat'
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
fid = fopen('output.dat', 'a');
if fid ~= -1
fprintf(fid, 'Dopisek: %s\n', date);
fclose(fid);
end
type 'output.dat'
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
===== 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):
tajna
wiad
omość
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.
t o
awm
jio
naś
adć
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:
x = szyfr('plik.txt', 'tajne.txt', 42);
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.:
szyfr('tajne.txt', 'odszyfrowane.txt', x);
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.