Edit detail for PraceSeSoubory revision 7 of 1

7
Editor: geon
Time: 2008/09/16 08:07:26 GMT+2
Note:

changed:
-
Základní práce se soubory
==========================
.. contents:: Obsah

Chcete-li v Pythonu pracovat se souborem, musíte ho nejdříve otevřít pomocí funkce `file("jmenoSouboru", způsob otevření)`. Otevřít ho můžete 3 hlavními způsoby:
 
- jen pro čtení - read - "r" nebo nic
- jen pro zápis - write - "w"
- jen pro přidávání - append - "a"
 
Je třeba po sobě soubory také zavírat, obzvláště u zápisu. Na uzavření souboru se používá metoda 'close()'.

Otevření pro čtení
--------------------

Příklad::

   soubor=file("mujSoubor.txt","r")
   soubor=file("mujSoubor.txt")  # zjednodušená verze
   
   ....
   
   soubor.close()
 
Načtení do proměnné::

   obsah=file("mujSoubor.txt").read()
   print obsah
   # při tomto použití se soubor nezavírá 
  
Načítání v cyklu, řádek po řádku::
 
   soubor=file("mujSoubor.txt")
   for radek in soubor:
       print radek
   soubor.close()
      
Tento způsob má nevýhodu, že při tisku se mezi každý řádek tiskne prázdný řádek navíc. Je to proto, že součástí každého řádku je i znak Enter ("\\n"), který je na konci každého řádku a sám příkaz print ještě přidává další Enter. Řešení jsou možné 2: 

- bud z řádku "\\n" odstraňovat (např. pomocí metody replace() nebo strip()) 
- nebo za slovem radek psát čárku, tedy `print radek,``
 
Otevření pro zápis
--------------------
Při tomto způsobu je soubor otevřen jen pro zápis, tedy nelze žádným způsobem z něj číst. Pokud soubor neexistoval, tak se vytvoří nový. Pokud existoval, jeho obsah je bez milosti smazán::
 
  soubor=file("highlow.txt","w")

  for pocet in range(100):
      soubor.write(str(pocet))

  soubor.close()
  
V tomto příkladu se do souboru zapíší číslice 0-99. Při zápisu do souboru je několik maličkostí, které mohou komplikovat život. 

- metodě write() je nutno předávat řetězec. Proto je tam str(pocet), funkce, která převádí číslo na řetězec. 
- takto jsou všechny čísla na jednom řádku - metoda write() nevkládá automaticky znak konce řádku "\\n". Pokud to chceme, musíme si ho tam vložit sami ručně::
 
    soubor.write(str(pocet)+"\n")

- třetí maličkost je, že pokud na konci neuzavřete soubor pomocí soubor.close(), je velmi pravděpodobné, že několik posledních zápisů nebo dokonce vše, se nezapíše, a soubor zůstane hotový buď z poloviny nebo dokonce úplně prázdný.
      

Otevření pro přidávání
----------------------
Chcete-li přidat něco na konec souboru, použijte "a"::
 
    soubor=file("mujSoubor.txt","a")
    soubor.write("pokus")
    soubor.close()

Rozšířené způsoby otevírání
===================================

a+
-----------------

Chcete-li číst a zároveň přidávat na konec, použijte "a+"::

    soubor=file("mujSoubor.txt","a+")
    soubor.write("pokus")
    soubor.seek(0)
    
    for radek in soubor:
        print radek,
    
    soubor.close()

r+
----------------
Chcete-li *přepisovat* obsah soubor, otevřete ho v režimu "r+"

    
Zapisování na začátek souboru
---------------------------------

Obecně je považována potřeba vkládat něco na začátek souboru jako příznak nedobrého návrhu. Snad žádný operační systém neumí *přímo* vkládat nové znaky jinam než na konec souboru. Takže si to člověk musí zařídit nějak sám:

- buď soubor načíst do paměti, sloučit s novým řetězcem a uložit zpátky
- nebo pokud je velký založit jiný soubor a nejdříve do něj zapsat nová data, a v cyklu řádky ze starého souboru. Nakonec smazat a přejmenovat.
- nebo použít modul mmap a následující trik::

    import os, mmap
    
    CONTENT = [ x**10 for x in range(10) ]
    
    BRICKS = "Tento trik umozni jednoduse vkladat retezce " \
             "na zacatek souboru.".split()
    
    FN = 'file-prepend.blabla.tmp'
    
    # Priprava: Ciselna rada do noveho souboru
    print "Writing:", CONTENT
    print >> open(FN, 'w'), CONTENT
    print
    
    # -----------
    
    def prepend(f, string):
        sl = len(string)
        if sl:
            mm = mmap.mmap(f.fileno(), 0)
            fl = mm.size()
            mm.resize(fl + sl)     # udelame misto
            mm.move(sl, 0, fl)     # posuneme obsah doprava
            mm[:sl] = string       # zapisene na zacatek
            mm.close()
    
    f = open(FN, 'r+')
    
    BRICKS.reverse()
    for word in BRICKS:
        print "Prepending:", word
        prepend(f, word + ' ')
    f.close()
    
    print
    print "Result:"
    print open(FN).read()
 



Základní práce se soubory

Chcete-li v Pythonu pracovat se souborem, musíte ho nejdříve otevřít pomocí funkce file("jmenoSouboru", způsob otevření). Otevřít ho můžete 3 hlavními způsoby:

  • jen pro čtení - read - "r" nebo nic
  • jen pro zápis - write - "w"
  • jen pro přidávání - append - "a"

Je třeba po sobě soubory také zavírat, obzvláště u zápisu. Na uzavření souboru se používá metoda 'close()'.

Otevření pro čtení

Příklad:

soubor=file("mujSoubor.txt","r")
soubor=file("mujSoubor.txt")  # zjednodušená verze

....

soubor.close()

Načtení do proměnné:

obsah=file("mujSoubor.txt").read()
print obsah
# při tomto použití se soubor nezavírá

Načítání v cyklu, řádek po řádku:

soubor=file("mujSoubor.txt")
for radek in soubor:
    print radek
soubor.close()

Tento způsob má nevýhodu, že při tisku se mezi každý řádek tiskne prázdný řádek navíc. Je to proto, že součástí každého řádku je i znak Enter ("\n"), který je na konci každého řádku a sám příkaz print ještě přidává další Enter. Řešení jsou možné 2:

  • bud z řádku "\n" odstraňovat (např. pomocí metody replace() nebo strip())
  • nebo za slovem radek psát čárku, tedy print radek,`

Otevření pro zápis

Při tomto způsobu je soubor otevřen jen pro zápis, tedy nelze žádným způsobem z něj číst. Pokud soubor neexistoval, tak se vytvoří nový. Pokud existoval, jeho obsah je bez milosti smazán:

soubor=file("highlow.txt","w")

for pocet in range(100):
    soubor.write(str(pocet))

soubor.close()

V tomto příkladu se do souboru zapíší číslice 0-99. Při zápisu do souboru je několik maličkostí, které mohou komplikovat život.

  • metodě write() je nutno předávat řetězec. Proto je tam str(pocet), funkce, která převádí číslo na řetězec.

  • takto jsou všechny čísla na jednom řádku - metoda write() nevkládá automaticky znak konce řádku "\n". Pokud to chceme, musíme si ho tam vložit sami ručně:

    soubor.write(str(pocet)+"\n")
    
  • třetí maličkost je, že pokud na konci neuzavřete soubor pomocí soubor.close(), je velmi pravděpodobné, že několik posledních zápisů nebo dokonce vše, se nezapíše, a soubor zůstane hotový buď z poloviny nebo dokonce úplně prázdný.

Otevření pro přidávání

Chcete-li přidat něco na konec souboru, použijte "a":

soubor=file("mujSoubor.txt","a")
soubor.write("pokus")
soubor.close()

Rozšířené způsoby otevírání

a+

Chcete-li číst a zároveň přidávat na konec, použijte "a+":

soubor=file("mujSoubor.txt","a+")
soubor.write("pokus")
soubor.seek(0)

for radek in soubor:
    print radek,

soubor.close()

r+

Chcete-li přepisovat obsah soubor, otevřete ho v režimu "r+"

Zapisování na začátek souboru

Obecně je považována potřeba vkládat něco na začátek souboru jako příznak nedobrého návrhu. Snad žádný operační systém neumí přímo vkládat nové znaky jinam než na konec souboru. Takže si to člověk musí zařídit nějak sám:

  • buď soubor načíst do paměti, sloučit s novým řetězcem a uložit zpátky

  • nebo pokud je velký založit jiný soubor a nejdříve do něj zapsat nová data, a v cyklu řádky ze starého souboru. Nakonec smazat a přejmenovat.

  • nebo použít modul mmap a následující trik:

    import os, mmap
    
    CONTENT = [ x**10 for x in range(10) ]
    
    BRICKS = "Tento trik umozni jednoduse vkladat retezce " \
             "na zacatek souboru.".split()
    
    FN = 'file-prepend.blabla.tmp'
    
    # Priprava: Ciselna rada do noveho souboru
    print "Writing:", CONTENT
    print >> open(FN, 'w'), CONTENT
    print
    
    # -----------
    
    def prepend(f, string):
        sl = len(string)
        if sl:
            mm = mmap.mmap(f.fileno(), 0)
            fl = mm.size()
            mm.resize(fl + sl)     # udelame misto
            mm.move(sl, 0, fl)     # posuneme obsah doprava
            mm[:sl] = string       # zapisene na zacatek
            mm.close()
    
    f = open(FN, 'r+')
    
    BRICKS.reverse()
    for word in BRICKS:
        print "Prepending:", word
        prepend(f, word + ' ')
    f.close()
    
    print
    print "Result:"
    print open(FN).read()