Spis treści

Operacje na plikach

Funckje load i save

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

% 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)

 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)

 png

image(x)

 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

 png

% Odwrócenie kolorów (negatyw)
y = 255 - x;
image(y(:,:,1));

 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)

 png

Niskopoziomowe operacje na plikach

Podstawowe kroki postepowania:

  1. Otworzenie pliku → uzyskujemy deskryptor pliku
  2. Operacje na pliku przy użyciu deskryptora: odczyt sekwencji danych, zapis, …
  3. Zamknięcie pliku

Otwieranie i zamykanie plików

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

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)

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()

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

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

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.