Blame programming-guidelines/cs/file-system.page

Packit 1470ea
Packit 1470ea
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2003/XInclude" type="topic" id="file-system" xml:lang="cs">
Packit 1470ea
Packit 1470ea
  <info>
Packit 1470ea
    <link type="guide" xref="index#specific-how-tos"/>
Packit 1470ea
Packit 1470ea
    <credit type="author copyright">
Packit 1470ea
      <name>Philip Withnall</name>
Packit 1470ea
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
Packit 1470ea
      <years>2015</years>
Packit 1470ea
    </credit>
Packit 1470ea
Packit 1470ea
    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>
Packit 1470ea
Packit 1470ea
    <desc>Jak přistupovat k souborovému systému</desc>
Packit 1470ea
  </info>
Packit 1470ea
Packit 1470ea
  <title>Přístup k souborovému systému</title>
Packit 1470ea
Packit 1470ea
  <synopsis>
Packit 1470ea
    <title>Shrnutí</title>
Packit 1470ea
Packit 1470ea
    

Při přístupu k souborovému systému byste měli mít na paměti několik negativních návrhových vzorů. Tento článek předpokládá znalost standardních API <link href="https://developer.gnome.org/gio/stable/GFile.html">GFile</link>, <link href="https://developer.gnome.org/gio/stable/GInputStream.html">GInputStream</link> a <link href="https://developer.gnome.org/gio/stable/GOutputStream.html">GOutputStream</link>.

Packit 1470ea
Packit 1470ea
    <list>
Packit 1470ea
      <item>

Pro přístup k souborům používejte asynchronní V/V. (<link xref="#asynchronous-io"/>)

</item>
Packit 1470ea
      <item>

Vždy používejte vhodné funkce k vytvoření názvů souborů a cest. (<link xref="#file-path-construction"/>)

</item>
Packit 1470ea
      <item>

Než použijete cestu k souboru, ověřte, že se nachází v očekávané složce. (<link xref="#path-validation-and-sandboxing"/>)

</item>
Packit 1470ea
      <item>

Používejte povinné profily pro řízení přístupu, aby se zaručily omezení v přístupu k souborům. (<link xref="#path-validation-and-sandboxing"/>)

</item>
Packit 1470ea
    </list>
Packit 1470ea
  </synopsis>
Packit 1470ea
Packit 1470ea
  <section id="asynchronous-io">
Packit 1470ea
    <title>Asynchronní V/V</title>
Packit 1470ea
Packit 1470ea
    

Většina V/V operací by měla být prováděna asynchronně. Což znamená bez blokování <link href="https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html">hlavního kontextu GLib</link>. Toho lze dosáhnout důsledným používáním variant *_async() a *_finish() jednotlivých V/V funkcí.

Packit 1470ea
Packit 1470ea
    <example>
Packit 1470ea
      

Například použijte <link href="https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read-async">g_input_stream_read_async()</link> a ne <link href="https://developer.gnome.org/gio/stable/GInputStream.html#g-input-stream-read">g_input_stream_read()</link>.

Packit 1470ea
    </example>
Packit 1470ea
Packit 1470ea
    

Synchronní V/V operace blokují hlavní smyčku, což znamená, že ostatní události, jako je vstup od uživatele, příchozí síťový paket, vypršení časového limitu a zpětné volání při nečinnosti, nejsou obsluhovány, dokud nedojde k návratu z blokující funkce.

Packit 1470ea
Packit 1470ea
    

Synchronní V/V je přijatelný za určitých okolností, kdy náklady na plánování asynchronní operace převýší cenu místního synchronního V/V v Linuxu. Například provedení drobného čtení z místního souborového systému nebo z virtuálního souborového systému, jako je <file>/proc</file>. Při takovém čtení by měly být použity raději nízkoúrovňové funkce g_open(), read() a g_close() místo GIO.

Packit 1470ea
Packit 1470ea
    

Soubory v uživatelově domovské složce se nepočítají jako místní, protože mohou být na síťovém souborovém systému.

Packit 1470ea
Packit 1470ea
    

Upozorňujeme, že alternativa – běh synchronního V/V v odděleném vlákně – je silně nedoporučován. Více informací viz <link xref="threading#when-to-use-threading">pokyny k vláknům</link>.

Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="file-path-construction">
Packit 1470ea
    <title>Sestavení cesty k souboru</title>
Packit 1470ea
Packit 1470ea
    

Názvy souborů a cesty nejsou běžné řetězce: na některých systémech mohou používat jiné kódování znaků, než UTF-8, zatímco u normálních řetězců je v GLib vždy zaručeno použití UTF-8. Z tohoto důvodu by pro sestavení a zpracování názvů souborů a cest měly používat speciální funkce. (Moderní linuxové systémy povětšinou pro kódování názvů souborů jednotně používají UTF-8, takže to v praxi není problém, ale tyto funkce by měly být přesto používány kvůli kompatibilitě s jinými systéme, jako jsou Windows používající v názvech souborů UTF-16.)

Packit 1470ea
Packit 1470ea
    <example>
Packit 1470ea
      

Například cesta k souboru by se měla sestavit pomocí <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-build-filename">g_build_filename()</link> namísto běžného <link href="https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strconcat">g_strconcat()</link>.

Packit 1470ea
    </example>
Packit 1470ea
Packit 1470ea
    

Když se to dělá takto, je v kódu jasnější, co se tím míní a také se tím zamezí zdvojení oddělovačů cest a vrácená cesta je kanonická (i když ne nutně absolutně).

Packit 1470ea
Packit 1470ea
    <example>
Packit 1470ea
      

Jiným příkladem by mohlo být rozložení cesty pomocí <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-basename">g_path_get_basename()</link> a <link href="https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-path-get-dirname">g_path_get_dirname()</link> namísto běžného <link href="https://developer.gnome.org/glib/stable/glib-String-Utility-Functions.html#g-strrstr">g_strrstr()</link> nebo jiných ručních vyhledávacích funkcí.

Packit 1470ea
    </example>
Packit 1470ea
  </section>
Packit 1470ea
Packit 1470ea
  <section id="path-validation-and-sandboxing">
Packit 1470ea
    <title>Ověřování cest a pískoviště</title>
Packit 1470ea
Packit 1470ea
    

Když název souboru nebo cesta pochází z externího vstupu, jako je webová stránka nebo uživatelský vstup, měly by být ověřeny, aby se zajistilo, že jejich vložení do cesty nevytvoří jen tak nějakou cestu. Například, když je název souboru sestavován z řetězce <file>~/</file> plus uživatelského vstupu a uživatel zadá <file>../../etc/passwd</file>, mohl by (potenciálně) získat přístup k citlivým informacím o účtech, v závislosti na tom, pod jakým účtem program běží a co dělá s daty načtenými ze sestavené cesty.

Packit 1470ea
Packit 1470ea
    

Tomu se dá předejít ověřováním sestavené cesty před tím, než ji použijete, pomocí funkce <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-resolve-relative-path">g_file_resolve_relative_path()</link>, která převede relativní cesty na absolutní a následně ověří, že cesta je pod danou kořenovou složku pískoviště příslušejícího operaci. Například, když kód stahuje soubor, mohl by pomocí <link href="https://developer.gnome.org/gio/stable/GFile.html#g-file-has-parent">g_file_has_parent()</link> ověřovat, že jsou všechny cesty pod <file>~/Downloads</file>.

Packit 1470ea
Packit 1470ea
    

Jako druhou linii obrany by všechny projekty, které přistupují k souborovému systému, měly zvážit poskytnutí povinného profilu pro řízení přístupu za použití systému jako jsou <link href="http://apparmor.net/">AppArmor</link> nebo <link href="http://selinuxproject.org/">SELinux</link>, čímž se omezí složky a soubory, které lze číst a zapisovat do nich.

Packit 1470ea
  </section>
Packit 1470ea
</page>