LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (29) - Úvod k práci se soubory

Soubory jsou prvním způsobem komunikace programu s okolím, kterým se bude seriál zabývat.

22.3.2006 06:00 | Jiří Václavík | Články autora | přečteno 40646×

Soubory jsou místa k ukládání nebo přenosu dat. Můžeme s nimi různými způsoby manipulovat. Právě tím se budeme v několika následujících dílech zabývat.

Ovladače

Práce se soubory spočívá ve vytvoření ovladače, což je datový typ, který potom soubor zprostředkovává. Pomocí něj lze do souboru zapisovat nebo naopak data získávat.

Narozdíl od dosud poznaných datových typů nemá ovladač souboru žádný prefix. To způsobuje, že s ním musíme pracovat v určitých případech trochu jinak - například při předávání podprogramům, kopírování apod. Obvykle musíme použít typegloby.

Důležité je, že práce s ovladačem je univerzální, ať se jedná a jakýkoliv zdroj dat. Nezáleží na tom, zda jde o socket, textový soubor, výstup roury nebo standardní vstup.

Existují 3 standardní ovladače, které jsou vždy automaticky otevřeny. Neodkazují na soubor, ale na výstup (obrazovku) nebo vstup (klávesnici): STDIN (standardní vstup), STDOUT (standardní výstup) a STDERR (standardní chybový výstup - jde o výpis hlášení, která nejsou ve zdrojovém kódu - například chyby).

Otevření ovladače

Ovladač je v případě textových souborů vytvářen funkcí open nebo sysopen. Později, až se setkáme například s prostředky meziprocesorové komunikace, zjistíme, že lze ovladače vytvářet i pro jiné soubory než textové.

Nejjednodušší volání funkce open má 2 parametry - jméno ovladače a jméno otvíraného souboru (pozor na přístupová práva). Jméno souboru může být absolutní i relativní. Před jménem souboru je třeba ještě dát najevo, jak bude soubor otevírán. Na výběr je jedna z následujících možností.

čtení

Uvedením < otevřeme soubor jen pro čtení:

open(DATA, "<soubor");

< je nastaveno implicitně, takže zápis bez určujícího znaku bude ekvivalentní.

open(DATA, "soubor");

Teď máme k dispozici ovladač DATA, se kterým můžeme pracovat stejně jako s kterýmkoliv jiným ovladačem.

zápis

Chcete-li zapisovat do souboru pomocí znaku > a soubor ještě neexistuje, vytvoří se. Pokud ale již existuje, bude původní obsah bez potvrzení smazán. Existuje metoda, která umožňuje vyšší kontrolu nad souborem. Tou jsou operátory pro zjišťování informací o souborech. V některém blízkém díle se jimi budeme také zabývat.

open(DATA, ">soubor");

přípis

Skrze ovladač pro přípis můžeme zapisovat, ale nikoliv mazat. Text se zapisuje na konec souboru. Pokud soubor neexistuje, vytvoří se.

open(DATA, ">>soubor");

standardní výstup

Otevření dalšího ovladače pro standardní výstup se dá využít například tam, kde se program až za běhu rozhoduje, kam bude zapisovat. Ovladač se vytváří jako zápis do souboru -.

open(DATA, ">-");

standardní vstup

A pro úplnost ještě dodejme, jak se vytvoří ovladač pro standardní vstup:

open(DATA, "<-");

Znak < je opět nepovinný.

open(DATA, "-");

roury

Ovladač jako zdroj dat může stejně dobře obsahovat i výstup nějakého shellového příkazu. Nyní přesměrujeme výstup příkazu ls / do ovladače a ovladač tak bude zpřístupňovat jména adresářů v kořenovém adresáři. Tentokrát se mód nepíše před název souboru ale až za něj.

open(DATA, "ls / |");

Pokud chceme naopak nějaký výstup přesměrovat na vstup - například na vstup příkazu more, použijeme zápis:

open(DATA, "| more");

Praktickým příkladem použití roury může být program, který odešle na danou adresu email:

$to = "nekdo\@nekde.cz";
$from = "ja\@mujpc.cz";
$subject = "Test";
$zprava = "text emailu\n";

open EMAIL, "| mail $to -s $subject -r $from" or die "Nelze spustit příkaz
k odeslání pošty.
$!";
print EMAIL $zprava;
close EMAIL;

zápis (přípis) a čtení zároveň

Pro vytvoření ovladače umožňujícího zápis i čtení je třeba před módy <, > nebo >> připsat znak +. U textových souborů není výskyt takových ovladačů příliš častý. Tento přístup se používá hojně například při socketové komunikaci, kdy posíláme i přijímáme data jediným kanálem.

módvýznam
+<kdekoliv v souboru lze číst i zapisovat
+>kdekoliv v souboru lze číst i zapisovat, ale stávající soubor je přepsán
+>>kdekoliv v souboru lze číst, připisovat se dá jen na konec, takže soubor není nikdy přepsán

Konkrétně:

open(DATA, "+<soubor");

verze se 3 argumenty

Mód lze uvést jako samostatný argument. Následující zápis funguje pro všechny módy. Pokud takto chcete použít rouru, musíte dát najevo jestli bude na začátku (|-) nebo na konci (-|).

open(DATA, ">>", "soubor");

kopie ovladačů

Za módy >, >>, <, +>, +>> a +< lze užít ampérsand. Tím vznikne stejný ovladač jako ovladač, jehož jméno je za ampérsandem.

open(OUT, ">&STDOUT");

Ovladač OUT posílá nyní data stejně jako STDOUT na standardní výstup.

Vytváření ovladačů funkcí sysopen

sysopen podobně jako open otevírá soubory, ale poskytuje nad nimi lepší přehled. Jako argumenty přijímá název ovladače, jméno souboru a příznaky oddělené operátorem |, které určují způsob otevření souboru.

PříznakVýznam
O_RDONLYpro čtení
O_WRONLYpro zápis
O_RDWRpro čtení a zápis
O_APPENDpro přípis
O_EXCLexistuje-li soubor, skončí neúspěchem
O_CREATpokud soubor neexistuje, bude vytvořen
O_TRUNCvymaže obsah
O_NONBLOCKpouze neblokující otevření

Chceme-li například do souboru připisovat a v případě, že neexistuje, jej vytvořit, funkce sysopen bude mít následující tvar:

sysopen(DATA, "soubor", O_WRONLY | O_CREAT | O_APPEND);

Zrušení ovladače

K zavření ovladače slouží příkaz close:

close DATA;

V případě, že je ovladač na konci programu ještě otevřený, měl by se zavřít automaticky sám.

Je dobré soubor nenechávat zbytečně dlouho otevřený a zavřít ho vždy, jakmile to je možné. Nikdy bychom třeba neměli nechávat otevřený soubor, jestliže program čeká na standardní vstup.

Práce s daty

Nyní si na několika příkladech ukážeme práci s otevřenými ovladači. Máme-li soubor otevřený pro čtení, můžeme k datům přistupovat přes nám již známý diamantový operátor. Jako 1. a nejjednodušší příklad napíšeme program, který opíše soubor data.txt na výstup.

open(DATA, "data.txt");
print <DATA>;
close DATA;

print je zde voláno v seznamovém kontextu. V každém prvku seznamu je řádek. Zkusme to samé s tím rozdílem, že zavoláme print opakovaně ve skalárním kontextu:

open(DATA, "data.txt");
print scalar $_ while <DATA>;
close DATA;

Teď vytvořme (hodně zjednodušenou) analogii příkazu cp. Bude umět jen kopírovat soubor do jiného. Oba soubory budou zadány. Naše verze zatím nebude přijímat ani argumenty z příkazového řádku. K tomu se dostaneme až v díle o spolupráci s příkazovým řádkem.

my $zdroj;
my $cil;

print "Zadejte zdrojový soubor: ";
chomp($zdroj = <STDIN>);
print "Zadejte cílový soubor: ";
chomp($cil = <STDIN>);

open(ZDROJ, $zdroj) or die "Nelze zapisovat do souboru: $!";
open(CIL, ">$cil") or die "Nelze otevřít soubor: $!";

print CIL <ZDROJ>;

close ZDROJ;
close CIL;

Prakticky veškerá činnost probíhá na jediném řádku, v němž kopírujeme jeden soubor do druhého.

Jako další ukázku si předvedeme přípis do souboru data.backup, kam přidáme nový řádek.

open(SOUBOR, ">> data.backup") or die "Nelze otevřít soubor: $!";
print SOUBOR "20060313 55000 0 0 0\n";
close SOUBOR;

Na závěr zjistíme 5 nejčastějších řádků ze souboru .bash_history nebo jiného souboru s historií příkazů. Prvním krokem bude načtení všech příkazů z tohoto souboru do hashe, kde klíčem bude vždy příkaz a hodnotou počet použití.

my $historie = $ENV{"HISTFILE"}; #cesta k souboru s historií
my %stat;

open(PRIKAZY, $historie) or die "Nelze otevřít soubor s historií!";

while ($prikaz = <PRIKAZY>){
    chomp $prikaz;
    $stat{$prikaz}++;
}

close PRIKAZ;

Poznámka - zápis cesty jako $ENV{"HISTFILE"} je lepším - tedy obecnějším - řešením než natvrdo zadaná cesta /home/user/.bash_history. V systémové proměnné $HISTFILE je uložena cesta k souboru s historií. Hashová proměnná %ENV souvisí se spoluprácí s operačním systémem, kterou se teprve budeme zabývat.

Podle hodnot ale nelze řadit hash. Abychom si zjednodušili práci, vytvoříme pole, do jehož každého prvku uložíme text ve formátu počet_použití_příkazu - příkaz.

foreach my $klic (keys %stat){
    $radky[$i] = "$stat{$klic} - $klic\n";
    $i++;
}

Pole číselně (nemusíme si všímat případného varování) seřadíme a tiskneme požadovaný počet řádků.

foreach my $klic (sort {$b <=> $a} @radky){
    print $klic;
    $pocet--;
    last if $pocet == 0;
}

Ještě aktualizujeme deklarace proměnných a získáváme celý zdrojový kód.

To byly nejzákladnější příkazy z oblasti práce se soubory, na které příště navážeme.

Verze pro tisk

pridej.cz

 

DISKUZE

Proč tak složitě 12.5.2006 13:30 Hynek (Pichi) Vychodil




Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

16.7.2018 1:05 /František Kučera

Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.


Přidat komentář

18.6.2018 0:43 /František Kučera
Červnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 21. 6. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: F-Droid, aneb svobodný software do vašeho mobilu. Kromě toho budou k vidění i vývojové desky HiFive1 se svobodným/otevřeným čipem RISC-V.
Přidat komentář

23.5.2018 20:55 /Ondřej Čečák
Od pátku 25.5. proběhne na Fakultě informačních technologií ČVUT v Praze openSUSE Conference. Můžete se těšit na spostu zajímavých přednášek, workshopů a také na Release Party nového openSUSE leap 15.0. V na stejném místě proběhne v sobotu 26.5. i seminář o bezpečnosti CryptoFest.
Přidat komentář

20.5.2018 17:45 /Redakce Linuxsoft.cz
Ve čtvrtek 31. května 2018 připravuje webový magazín BusinessIT ve spolupráci s Best Online Média s.r.o. pátý ročník odborné konference Firemní informační systémy 2018. Akce proběhne v kongresovém centru Vavruška (palác Charitas), Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00 hod. dopoledne do cca 15 hod. odpoledne. Konference je zaměřena na efektivní využití firemních informačních systémů a na to, jak plně využít jejich potenciál. Podrobnější informace na webových stránkách konfrence.
Přidat komentář

14.5.2018 7:28 /František Kučera
Květnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 17. 5. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát na téma: Audio – zvuk v GNU/Linuxu.
Přidat komentář

7.5.2018 16:20 /František Kučera
Na stránkách spolku OpenAlt vyšla fotoreportáž Pražské srazy 2017 dokumentující srazy za uplynulý rok. Květnový pražský sraz na téma audio se bude konat 17. 5. 2018 (místo a čas ještě upřesníme).
Přidat komentář

17.4.2018 0:46 /František Kučera
Dubnový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 4. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tématem tohoto srazu bude OpenStreetMap (OSM) aneb svobodné mapy.
Přidat komentář

16.3.2018 22:01 /František Kučera
Kulatý OpenAlt sraz v Praze oslavíme klasicky: u limonády a piva! Přijďte si posedět, dát si dobré jídlo a vybrat z mnoha piv do restaurace Kulový blesk, který najdete v centru Prahy nedaleko metra I. P. Pavlova na adrese Sokolská 13, Praha 2. Sraz se koná ve čtvrtek 22. března a začínáme v 18:00. Heslo: OpenAlt. Vezměte s sebou svoje hračky! Uvítáme, když si s sebou na sraz vezmete svoje oblíbené hračky. Jestli máte nějaký drobný projekt postavený na Arduinu, nějakou zajímavou elektronickou součástku, či třeba i pěkný úlovek z crowdfundingové akce, neváhejte. Oslníte ostatní a o zábavu bude postaráno.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

20.2.2018 18:48 / Ivan Majer
portal

20.2.2018 15:57 / Jan Havel
Jak využíváte služby cloudu v podnikání?

16.1.2018 1:08 / Ivan Pittner
verejna ip od o2 ubuntu

15.1.2018 17:26 / Mira Harvalik
Re: Jak udělat HTML/Javascript swiping gallery do mobilu?

30.12.2017 20:16 / Michal Knoll
odmocnina

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2018) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze