Umíme to s Delphi, 24. díl – práce se soubory podrobněji, 1. část

Práci se soubory jsme se již v našem seriálu věnovali, avšak seznámení bylo velmi stručné. V dnešní a příští kapitole se na soubory podíváme podrobněji. Dnes si naznačíme rozdíly mezi jednotlivými typy souborů a povíme si obecný úvod k práci se soubory – jak je otvírat, jak z nich číst, jak zapisovat.
Vyjmenujeme si všechny důležité funkce Object Pascalu pro práci se soubory. Za týden si vysvětlíme vyhledávání souborů a podrobně se podíváme na jednotlivé typy souborů.

Přestože jsme se již práci se soubory v našem seriálu věnovali (konkrétně v 11. dílu), vracíme se dnes k téže problematice. Důvodem je jednak maximální stručnost, se kterou jsme si soubory popsali ve zmíněné 11. kapitole, a jednak impuls vzešlý od jednoho ze čtenářů. Tento čtenář správně zmínil, že ač jde spíše o pascalskou složku programování v Delphi, bude se toto téma všem pravověrným delphařům jistě hodit. Delphi navíc přináší mnoho procedur a funkcí pro práci se soubory, které v předchozích verzích Pascalu nebyly k dispozici.

Soubory v Object Pascalu – trocha teorie

Podívejme se, jak zní definice souboru: soubor je lineární posloupností složek libovolného typu, které jsou průběžně číslovány. Číslo první složky je 0. Začátek souboru nazýváme tzv. hlavičkou souboru, konec je signalizován symbolem konce souboru.

Co touto definicí rozumíme? Soubor je zkrátka posloupností údajů. Počet těchto údajů není dopředu (při deklaraci) nijak určen. Údaje v souboru jsou číslovány (i když to nutně nemusí být žádné explicitně viditelné číslování – viz dále). V každém případě je číslo prvního údaje 0. Údaj v souboru může být v podstatě libovolného typu, i strukturovaného, s následujícími výjimkami a omezeními:

  • typ musí mít konstantní velikost vyčíslitelnou v době překladu;
  • nelze použít typ ukazatel (a to v žádné podobě).
V důsledku těchto dvou podmínek tedy soubor nemůže obsahovat dynamická pole, řetězce (bez udané délky), třídy, objekty, ukazatele, variantní záznamy, další soubory a nebo strukturované typy obsahující v libovolné složce některý z těchto typů (uvedená omezení neplatí pro soubory bez udaného typu).

Podívejme se raději na příklad záznamu, který není povolen jako údaj souboru. Používáme totiž řetězec bez udané délky.

type Clovek  = record
  Jmeno : string;
  Prijmeni : string;
  end;

type Soubor = File of Clovek;
// v souboru nesmí být záznam s řetězcem bez udané délky

// Řešení tohoto problému je průzračně jednoduché:
type Clovek  = record
  Jmeno : string[20];
  Prijmeni : string[20];
  end;

type Soubor = File of Clovek;

Obecně lze říci, že přístup k souborům je sekvenční, to znamená, že k údaji číslo N se dostaneme tak, že přečteme (nebo chcete-li, projdeme) všechny údaje s čísly 0 až N-1. Soubory, které nejsou textové, můžeme ovšem zpracovávat i tzv. přímým přístupem. V tom případě můžeme rovnou přistupovat k záznamu udaného pořadového čísla bez nutnosti projít celý soubor od začátku.

Rozdíl mezi oběma přístupy si můžete (zjednodušené) přirovnat k rozdílu mezi dvěma záznamovými médii: pevný disk je ukázka přímého přístupu k datům, magnetofonová kazeta demonstruje sekvenční přístup.

V Object Pascalu (stejně jako v předchozích verzích Turbo Pascalu) existují tři typy souborů:

  • soubory bez udaného typu;
  • soubory s udaným typem;
  • textové soubory.
Každý z těchto tří typů souborů má své výhody a nevýhody a každý je vhodný v určité, specifické situaci. Na jednotlivé typy a na konkrétní způsob práce s nimi se podíváme v následujících podkapitolách. Nejprve ale věnujeme jednu kapitolu těm fragmentům práce se soubory, které se neliší typ od typu.

Práce se soubory – obecné pravdy

Následující řádky platí pro soubory všech tří zmíněných typů.

Spojení proměnné se souborem

Pracujeme-li v Object Pascalu se souborem, pracujeme de facto s proměnnou typu soubor. Tato proměnná musí být příslušným způsobem deklarována (způsob deklarace závisí na typu souboru a popíšeme si jej vždy v kapitole o příslušném typu souboru). Před prvním použitím proměnné typu soubor ovšem musíme tuto proměnnou spojit s fyzickým souborem na disku. Pokud toto spojení neprovedeme, je generována výjimka a práce se souborem nebude fungovat. K zmíněnému spojení se používá funkce AssignFile:

procedure AssignFile(var F: SouborJakehokolivTypu; NazevSouboru: string);

Prvním parametrem funkce AssignFile je proměnná typu soubor (ať už textový, netypovaný nebo s udaným typem), druhým parametrem je název souboru včetně případné adresářové cesty. Příklady:

AssignFile(F, `nazdar.txt`);
if OpenDialog.Execute then
    AssignFile(F, OpenDialog.FileName);

Poznámky: V Turbo Pascalu se místo procedury AssignFile používala procedura Assign. Klíčové slovo Assign se ovšem v Delphi používá k jiným účelům (je to metoda mnoha tříd). Ovšem chcete-li, můžete jej i přesto používat, jen před ním musíte uvést kvalifikátor jednotky System, např.

System.Assign(Soubor, ‘nazev.txt’);

Otevření souboru

Máme-li fyzický soubor (byť dosud neexistující!) přiřazen k proměnné typu soubor, je nutné soubor před první operací otevřít. Způsoby otvírání se mírně liší podle typu souboru, nicméně základní kostra je stále stejná, proto si otvírání uvedeme na tomto místě a posléze se jen zmíníme o jednotlivých odlišnostech.

K otvírání souboru se používá procedur Reset, Append a Rewrite. Mají vždy jediný parametr (až na výjimky popsané níže), kterým je proměnná typu soubor.

Procedura Reset

procedure Reset(var F : Soubor);

Otvírá soubor pro čtení i pro zápis, textové soubory otvírá pouze pro čtení. U netypovaných souborů má ještě druhý parametr udávající velikost přenášeného bloku dat. Neexistuje-li fyzicky příslušný soubor, dojde k chybě (je generována výjimka). Je-li otevíraný soubor již otevřen, dojde nejprve k jeho uzavření a následně k opětovnému otevření. Příklad:

var
  Soubor: File;

begin
  AssignFile(Soubor, `nazdar.txt`); // přiřadíme název
  Reset(Soubor); // otevřeme soubor
  ...
  CloseFile(Soubor); // uzavřeme soubor
end;

Procedura Append

procedure Append(var F: TextovýSoubor);

Je použitelná pouze pro textové soubory. Otvírá existující soubor pro zápis a nastaví aktuální pozici na konec souboru (tzv. otevření souboru pro přípis). Neexistuje-li fyzicky příslušný soubor, dojde k chybě (je generována výjimka). Je-li otevíraný soubor již otevřen, dojde nejprve k jeho uzavření a následně k opětovnému otevření. Příklad:

var
  Soubor: TextFile; // lze použít i klíč. slovo Text

begin
  AssignFile(Soubor, `nazdar.txt`); // přiřadíme název
  Append(Soubor); // otevřeme soubor
  ...
  CloseFile(Soubor); // uzavřeme soubor
end;

Procedura Rewrite

procedure Rewrite(var F: Soubor);

Vytvoří a otevře nový soubor. Textové soubory otvírá pouze pro zápis. U netypovaných souborů může mít ještě druhý parametr udávající velikost přenášeného bloku dat. Pokud otvíraný soubor již existuje, je vymazán a znovu založen. Je-li otvíraný soubor již otevřen, dojde nejprve k jeho uzavření a následně k opětovnému otevření jako prázdný. Aktuální pozice je vždy nastavena na začátek souboru.

var
  Soubor: File;

begin
  AssignFile(Soubor, `nazdar.txt`); // přiřadíme název
  Rewrite(Soubor); // založíme nový soubor
  ...
  CloseFile(Soubor); // uzavřeme soubor
end;

Protože „speciální“ vlastnosti jednotlivých procedur jsou poněkud matoucí, uvedeme si ještě tabulku, která (snad:-)) přehledně shrne způsoby otevření pro jednotlivé typy souborů:

Pro čtení Pro zápis Pro přípis
Soubor s udaným typem Reset, Rewrite Reset, Rewrite --
Soubor bez udaného typu Reset, Rewrite Reset, Rewrite --
Textový soubor Reset Rewrite Append

Čtení ze souboru a zápis do souboru

Máme-li soubor korektně otevřen, nic nám nebrání z něj číst, resp. do něj zapisovat. K tomu se používají procedury Read, ReadLn, BlockRead, resp. Write, WriteLn, BlockWrite. Každá z těchto procedur se ovšem používá u souborů různých typů, proto se jimi nebudeme na tomto místě podrobně zabývat a projdeme si je jen velmi stručně:

Procedura Read

procedure Read(F: Soubor, Pol1 [, Pol2,...,Poln]);

Tato procedura je asi nejpoužívanější „načítací“ procedurou. Umožňuje načíst jednu nebo více hodnot z textového a typovaného souboru. Jejím prvním parametrem je proměnná typu soubor (může být textový nebo s udaným typem, nesmí být netypovaný). Dalšími parametry jsou položky, které ze souboru chceme načítat. Pořadí a typ proměnných musí ovšem přesně odpovídat pořadí a typu položek v souboru, jinak nebude načítání korektní.

Např. pokud máme v textovém souboru údaje uspořádány takto:

Kadlec Václav 10 20 30 40 50 Novák Jiří 60 70  80 90 100 … atd.,

nabízela by se možnost načítat celý jeden údaj takto:

var
  Jmeno, Prijmeni: String[20];
  I1, I2, I3, I4, I5: Integer;

begin
  ...
  Read(Soubor, Prijmeni, Jmeno, I1, I2, I3, I4, I5);
  ...
end;

Tento příklad by byl funkční jen v tom případě, že by za příjmením (a jménem) bylo tolik mezer, aby celková délka příjmení (a jména) byla 20 znaků (viz deklarovaná délka). Soubor by tedy musel vypadat nějak takto:

Kadlec              Václav              10 20 30 40 50 ... atd.,

Procedura ReadLn

procedure ReadLn(var F: Text; Pol1 [, Pol2, ...,PolN]);

Tato procedura je velmi podobná proceduře Read, ale poté, co dokončí čtení, přejde v textovém souboru na další řádku. Můžeme ji také použít bez dalších parametrů, pak se pouze nastaví pozice v souboru na další řádek.

Procedura BlockRead

procedure BlockRead(var F: File; var Buf;    Count: Integer [; var AmtTransferred: Integer]);

Tato procedura načítá jeden nebo více záznamů ze souboru s neudaným typem. Parametr Buf je jakákoliv proměnná, do které se bude zapisovat přečtená hodnota, Count udává počet záznamů, které se mají ze souboru přečíst (pokud jich v souboru existuje méně, jsou přečteny všechny). Aktuální počet přečtených záznamů (tedy méně nebo rovno parametru Count) je vracen v nepovinném parametru AmtTransferred. Pokud není parametr AmtTransferred zadán a přečte se méně záznamů, než udává proměnná Count, dojde k chybě (buď je generována výjimka EinOutError, nebo je nutné chybu detekovat pomocí IOResult, viz níže). Velikost načítaného bloku (tedy množství bytů načtených najednou) se nastavuje při otvírání souboru – viz výše.

Procedura Write

procedure Write(F: Soubor, Pol1 [, Pol2,...,Poln]);

Analogická procedura k Read. Umožňuje zapsat jednu nebo více hodnot do textového a typovaného souboru. Jejím prvním parametrem je opět proměnná typu textového nebo typovaného souboru a v dalších parametrech se uvádí údaje, které chceme zapsat.

Procedura WriteLn

procedure WriteLn(var F: Text; Pol1 [, Pol2, ...,PolN]);

Tato procedura je opět analogií k proceduře ReadLn. Po dokončení aktuálního zápisu přejde na další řádku. Používat se může pouze v textovém souboru.

Procedura BlockWrite

procedure BlockWrite(var F: File; var Buf;    Count: Integer [; var AmtTransferred: Integer]);

Do třetice analogie, tentokrát s BlockRead. Pracuje obdobně, zapisuje jeden nebo více záznamů do souboru bez udaného typu.

Uzavření souboru

Po skončení práce se souborem je nutné jej uzavřít. K tomu se používá procedura CloseFile (příp. System.Close):

procedure CloseFile(var F: Soubor);

Tato procedura ukončuje spojení mezi fyzickým souborem a proměnnou typu soubor. Po uzavření souboru dojde k jeho aktualizaci (tj. bude zaručeno, že všechny údaje, které jsme do souboru při předchozí práci zapisovali, v něm opravdu budou.) Před uzavřením souboru není jisté, že všechny zapisované údaje skutečně v souboru fyzicky jsou (mohou se „povalovat“ v nejrůznějších bufferech, vyrovnávacích pamětech apod.). Příklad:

var
  Soubor: TextFile;

begin
  if OpenDialog.Execute then begin
    AssignFile(Soubor, OpenDialog.FileName); // přiřadíme název
    Append(Soubor); // otevřeme soubor
    ...
    CloseFile(Soubor); // uzavřeme soubor
  end;
end;

Chyby při práci se soubory

Pokud sledujete náš seriál pravidelně, asi víte, jak se dají chyby při práci se soubory ošetřovat pomocí mechanismu výjimek (viz např. 11. díl – Výjimky nebo 11. díl – Soubory; číslování kapitol se v té době trochu zadrhlo, ale naštěstí ne nadlouho;-)).

Existuje ovšem ještě jeden způsob, jak chyby ošetřovat. Je mnohem méně elegantní a je zachován spíše kvůli historickým souvislostem, nicméně pro úplnost jej v krátkosti zmíním. Základním kamenem tohoto způsobu je funkce IOResult a direktiva překladače {$I+}, {$I-}.

Direktiva překladače {$I+}, {$I-} (nebo také {$IOCHECKS ON}, {$IOCHECKS OFF}) říká, budou-li automaticky kontrolovány výsledky (kódy ukončení) vstupně/výstupních operací. Je-li tato kontrola zapnuta (tj. {$I+}) a pokud vstupně/výstupní operace vrátí nenulový výsledek (tj. nastala nějaká chyba), je generována výjimka EInOutError. To je standardní chování, neboť takto nastavená direktiva je přednastavenou hodnotou. Vzniklou výjimku můžeme testovat (bloky try, except, finally) a ošetřovat. Pokud ovšem automatickou kontrolu vypneme ({$I-}), žádná výjimka generována nebude a my musíme vstupně/výstupní chyby testovat sami voláním funkce IOResult.

Je-li nastavena direktiva překladače {$I-}, vrací funkce IOResult kód ukončení poslední vstupně/výstupní operace. Pokud při takto nastavené direktivě překladače nastane nějaká vstupně/výstupní chyba, všechny následné vstupně/výstupní operace jsou ignorovány (nebudou se provádět), dokud není zavolána funkce IOResult. Zavoláním funkce IOResult se vymaže interní chybový příznak a následující vstupně/výstupní operace jsou dále normálně prováděny.

V praxi to znamená, že před jakoukoliv potencionálně nebezpečnou vstupně/výstupní operací (tj. prakticky před každou) bychom měli vypnout direktivu automatické kontroly vstupně/výstupních chyb ({$I-}) a vzápětí zavolat funkci IOResult s testováním chybového stavu. Podívejte se na příklad.

Máme formulář (frmHlavni), na něm jediné tlačítko (btnVelikost) a OpenDialog (dlgOpen). Po stisku tlačítka se otevře dialog pro otevření souboru a po vybrání nějakého souboru (nebo zadání názvu do editačního pole) se vypíše jeho velikost v bytech. Pokud soubor neexistuje (uživatel zadal nesmyslné jméno), nebo dojde-li k jiné chybě (soubor není dostupný, apod.), vypíše se chybová hláška.

procedure TfrmHlavni.btnVelikostClick(Sender: TObject);
var
  F: file of Byte;

begin
  if dlgOpen.Execute then begin
    AssignFile(F, dlgOpen.FileName);
    {$I-} // vypnutí automatické kontroly
    Reset(F); // pokus o otevření souboru
    {$I+} // zapnutí automatické kontroly
    if IOResult = 0 then begin
      MessageDlg(`Velikost souboru v bytech: ` + IntToStr(FileSize(S)),
        mtInformation, [mbOk], 0);
      CloseFile(S);
    end else
      MessageDlg(`Chyba pøi práci se souborem!`, mtWarning, [mbOk], 0);  end;
end;

Procedury a funkce použitelné pro soubory všech typů

Object Pascal nabízí mnoho a mnoho procedur a funkcí souvisejících s prací se soubory, které můžeme použít bez ohledu na typ otevřeného souboru. Některé z nich pracují přímo s vlastním souborem, některé pouze s jeho názvem apod. Stručný přehled nejdůležitějších z nich přináší následující tabulka:

Procedura/Funkce Popis
function ChangeFileExt(const FileName, Extension: string): string; Změní příponu souboru na zadanou a vrací nový název souboru
procedure ChDir(S: string); Procedura změní aktuální adresář na cestu uvedenou v parametru S. Pokud součástí řetězce S je také označení diskové jednotky, dojde i ke změně aktuálního disku.
function CreateDir(const Dir: string): Boolean; Vytvoří nový adresář (složku). Vrací True, byl-li adresář korektně vytvořen, a False, došlo-li k chybě.
function DeleteFile(const FileName: string): Boolean; Vymaže z disku soubor, jehož název (a cestu) zadáme v parametru FileName. Pokud soubor nemůže být smazán (případně pokud neexistuje), je vrácena hodnota False, jinak True.
function DirectoryExists(Name: string): Boolean; Tato funkce se používá k zjištění, zda existuje zadaný adresář. Pokud ano, je vráceno True, jinak False. Cesta může být samozřejmě zadána jako absolutní (úplná) nebo relativní (od aktuálního adresáře).
function DiskFree(Drive: Byte): Int64; Vrací počet volných bytů na specifikovaném disku. Disky se označují celými čísly, přičemž 0 = aktuální disk, 1 = disk A, 2 = disk B, atd. DiskFree vrací hodnotu –1, pokud zadaný disk neexistuje (nebo je neplatný).
function DiskSize(Drive: Byte): Int64; Vrací velikost disku v bytech. Způsob předávání parametru je stejný jako u funkce DiskFree.
function Eof(var F): Boolean; Vrací True, bylo-li dosaženo konce souboru, jinak vrací False.
procedure Erase(var F: soubor); Vymaže z disku soubor, který je spojen s proměnnou typu soubor F. F může být proměnná souboru libovolného typu. Rozdíl mezi Erase a DeleteFile spočívá v tom, že funkci DeleteFile předáváme název souboru, zatímco funkci Erase proměnnou, která je s daným souborem asociována (spojena).
function ExcludeTrailingBackslash(const S: string): string; Ze zadané cesty (parametr S) vymaže případné závěrečné zpětné lomítko (\), pokud jej tato cesta jako svůj poslední znak obsahuje. Pokud zadaná cesta nekončí zpětným lomítkem, vrací funkce kopii parametru S.
function ExpandFileName(const FileName: string): string; Expanduje (rozšíří) zadanou cestu na úplnou, tj. včetně označení disku a úplné adresářové cesty.
function ExtractFileDir(const FileName: string): string; Ze zadané cesty vrací disk a adresářovou cestu (bez názvu souboru).
function ExtractFileDrive(const FileName: string): string; Ze zadané cesty vrací pouze označení disku (např. C:).
function ExtractFileExt(const FileName: string): string; Ze zadané cesty vrací pouze příponu souboru (např. .txt).
function ExtractFileName(const FileName: string): string; Ze zadané cesty vrací pouze název souboru včetně přípony (např. ahoj.txt).
function ExtractFilePath(const FileName: string): string; Ze zadané cesty vrací pouze adresářovou strukturu bez názvu souboru (např. c:\nazdar\).
function ExtractRelativePath(const BaseName, DestName: string): string; Funkce vrací relativní cestu k souboru. Nejprve je nutno předat „vztažný“ adresář (tj. adresář, ke kterému se má výsledná relativní cesta vztahovat) a úplnou cestu k souboru. Výsledkem bude relativní cesta k souboru od „vztažného“ adresáře (např. cau\ahoj.txt).
function ExtractShortPathName(const FileName: string): string; Převede zadanou cestu na „dosový“ formát 8.3 (8 znaků název, 3 znaky přípona). Například cestu C:\Program Files\Ahoj.txt převede na C:\Progra~1\Ahoj.txt.
function FileDateToDateTime(FileDate: Integer): TDateTime; Používá se ke konverzi údaje o datumu a času souboru do hodnoty TDateTime. Třída TDateTime reprezentuje údaje o času o datumu v rámci knihovny VCL.
function FileExists(const FileName: string): Boolean; Testuje, zda existuje zadaný soubor. Vrací True, pokud ano.
function FileSetAttr(const FileName: string; Attr: Integer): Integer; Nastavuje atributy zadanému souboru. Navrací hodnotu nula, pokud nastavení proběhlo úspěšně, jinak vrací chybovou návratovou hodnotu Windows. Hodnota parametru Attr je vytvořena zkombinováním konstant atributů souborů, např.

FileSetAttr(`MyFile.sys`, faReadOnly or faSysFile);

procedure FindClose(var F: TSearchRec); Uvolňuje paměť alokovanou funkcí FindFirst, ukončuje sekvenci FindFirst/FindNext (podrobně viz příští díl seriálu).
function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer; Hledá první výskyt souboru, jehož název je uveden v parametru Path a jehož atributy jsou uvedeny v parametru Attr. Podrobnější popis bude v příštím díle seriálu.
function FindNext(var F: TSearchRec): Integer; Vrací další položku odpovídající předchozímu volání funkce FindFirst. Podrobnější popis bude v příštím díle seriálu.
function ForceDirectories(Dir: string): Boolean; Vytvoří zadaný adresář a všechny podadresáře, které dosud neexistují. Pokud např. chcete v Dosu nebo ve Windows vytvořit adresář ‚C:\AHOJ\NAZDAR\CAU‘, musí již v kořenovém adresáři disku C existovat adresáře AHOJ a NAZDAR, aby mohl být vytvořen adresář CAU. Funkce ForceDirectories tuto nutnost určitým způsobem obchází, neboť všechny potřebné adresáře vytvoří.
function GetCurrentDir: string; Vrací jméno aktuálního adresáře.
function RemoveDir(const Dir: string): Boolean; Smaže z disku zadaný adresář, vrací True v případě úspěchu, jinak False. Mazaný adresář musí být prázdný!
function IncludeTrailingBackslash(const S: string): string; Pokud zadaná cesta nekončí zpětným lomítkem, vrátí tutéž cestu s přidaným závěrečným zpětným lomítkem.
function IsPathDelimiter(const S: string; Index: Integer): Boolean; Udává (vrací True), zda znak na zadané pozici je zpětné lomítko. První znak má číslo 0, druhý číslo 1, apod.
function MatchesMask(const Filename, Mask: string): Boolean; Vrací True, pokud zadaný soubor vyhovuje zadané souborové masce (např. soubor Ahoj.txt vyhovuje masce A*.t??, ale nevyhovuje masce A*.?k?).
procedure ProcessPath (const EditText: string; var Drive: Char; var DirPart: string; var FilePart: string); Rozdělí zadanou cestu k souboru do jednotlivých proměnných – disk, cesta, soubor.
function RenameFile(const OldName, NewName: string): Boolean; Přejmenuje soubor zadaný v parametru OldName na název specifikovaný v NewName. V případě úspěchu vrací True, jinak False.
function SetCurrentDir(const Dir: string): Boolean; Nastaví aktuální adresář podle parametru zadaného v parametru Dir.

Funkce uvedené v této tabulce se vyskytují v programových jednotkách System, SysUtils, FileCtrl a Masks. Pokud vám tedy překladač při pokusu o použití některé z uvedených funkcí hlásí chybu Undeclared Identifier, postačí, když se v nápovědě podíváte, ve kterém modulu je daná funkce deklarována, a tento modul připíšete do sekce Uses vašeho modulu. (A pokud se vám nechce číst nápovědu, můžete do sekce Uses přidat všechny tři moduly – s výjimkou modulu System, neboť ten je použit automaticky. Ale nikde neříkejte, že jsem vám to poradil já:-), protože velikost výsledného *.EXE souboru se zvětšuje s každou uvedenou jednotkou) .

Kromě tohoto stručného a krátkého :-) přehledu existuje ještě celá řada dalších funkcí pracujících se soubory pomocí řetězců, případně proměnných typu soubor, ale také velká množina funkcí pracujících se soubory prostřednictvím handlers. Těmi se ale již z pochopitelných důvodů nemůžeme zabývat…

Příště pokračujeme

V příštím díle seriálu budeme pokračovat v popisu souborů. Nejprve si vysvětlíme vyhledávání pomocí procedur FindFirst a FindNext. Pak se konkrétně a podrobně podíváme na specifika práce s jednotlivými typy souborů. Vytvoříme také několik demonstračních aplikací.

Témata článku: Software, Windows, Programování, Práce, Fyzický soubor, Základní kostra, Libovolný soubor, BAS-de, Funkce, Filename, Dokončené dílo, Cesta, Caa, Code, Jednotlivý soubor, Jednotlivý díl, Nesmyslné jméno, Byte, Nový adresář, Jednotlivé položky, Pascal, Textový řetězec, Read, Reset, Díl

Určitě si přečtěte

Tesla chce změnit nákladní dopravu. Její elektrický náklaďák má ohromující parametry

Tesla chce změnit nákladní dopravu. Její elektrický náklaďák má ohromující parametry

** Tesla představila elektrický kamion ** Má obdivuhodný výkon i dojezd ** Prodávat by se měl už za dva roky

17.  11.  2017 | Vojtěch Malý | 199

Elektronika, která nepotřebuje kabel ani baterii. Živí se rádiovým šumem

Elektronika, která nepotřebuje kabel ani baterii. Živí se rádiovým šumem

** Každá elektrická krabička má konektor pro napájení nebo baterii ** Jenže pozor, jednou by to tak nemuselo být ** Drobná elektronika se může živit rádiovými vlnami

14.  11.  2017 | Jakub Čížek | 15

Nejlepší notebooky do 10 tisíc, které si teď můžete koupit

Nejlepší notebooky do 10 tisíc, které si teď můžete koupit

** I pod hranicí desíti tisíc korun existují dobře použitelné notebooky ** Mohou plnit roli pracovního stroje i zařízení pro zábavu ** Nejlevnější použitelný notebook koupíte za pět a půl tisíce

16.  11.  2017 | Stanislav Janů | 53


Aktuální číslo časopisu Computer

Otestovali jsme 5 HDR 4K televizorů

Jak natáčet video zrcadlovkou

Vytvořte si chytrou domácnost

Radíme s koupí počítačového zdroje