Cvičenie 6 - práca so súbormi
Príprava:
- Stiahnite si cvičný
adresár a rozbaľte z neho adresár cv6 pomocou
programu 7-Zip (pravý klik na stiahnutý zip, v menu
vybrať 7-Zip a otvoriť, potom vytiahnuť adresár zo zipu napr. na
desktop alebo na disk E:).
Vi Windows je dôležité použiť 7-Zip a nie bežný zip, lebo zip
pokazí dátumy súborov a nebudete vedieť riešiť Úlohu 3.
V ďalšom texte budeme hovoriť o adresári cv6 (resp. v
programoch E:\cv6).
- Prečítajte si posledné 4 strany z prezentácie
k správe súborov
- V prípade nejasností skúste aj dokumentáciu Pythonu k modulom
os, os.path
a time,
prípadne aj k iným modulom.
- Na poslednej strane prezentácie sú funkcie prechadzaj
a prechadzaj2, ktoré implementujú dvomi rôznymi spôsobmi
prechádzanie cez všetky súbory a podadresáre v danom podstrome
adresárov (skopíroval som ich sem, lebo copy/paste z pdf súboru
býva niekedy problém):
import os
def prechadzaj(cesta,level = 0):
print('
'*2*level+os.path.basename(cesta))
level+=1
for fn in os.listdir(cesta):
fpath =
os.path.join(cesta,fn)
if
os.path.isfile(fpath):
print(' '*2*level+fn)
elif
os.path.islink(fpath):
print(' '*2*level+'--> ',fn)
else:
prechadzaj(fpath,level)
def prechadzaj2(cesta):
toplevel = cesta.count(os.path.sep)
for dirpath,subdirs,files in
os.walk(cesta):
level =
dirpath.count(os.path.sep)-toplevel
print('
'*level*2+os.path.basename(dirpath))
for fn in files:
print(' '*(level+1)*2+fn)
Skopírujte si tieto dve funkcie do súboru a
vyskúšajte ich na adresári cv6 prípadne na nejakom jeho
podaresári.
Aby ste mohli ísť ďalej, treba pochopiť, ako fungujú
tieto funkcie.
V úlohách potom použite ako vzor jednu z nich, ktorá vám viac
vyhovuje (alebo ktorej lepšie rozumiete, a teda ju budete lepšie
vedieť zmeniť/doplniť pre konkrétny účel).
Dôležité:
- V celom cvičení nezabudnite na zdvojovanie opačných
lomítok v reťazcových konštantách (napr. "E:\\cv6").
- V celom cvičení pri rozoberaní a skladaní mien súborov a
celých ciest používajte nové funkcie naštudované v
prezentácii, nesnažte sa to robiť všeobecnými funkciami na
spracovanie reťazcov.
Úloha 1:
Naprogramujte funkciu pocetprip(adresar, pripony), ktorej
výsledok je počet súborov v celom podstrome adresárov začinajúcich
od adresar, ktorých prípona (extension) je niektorá zo
zoznamu pripony. Nezabudnite, že vo Windows sa mená súborov
(a aj ich prípony) porovnávajú bez ohľadu na malé a veľké písmená
(Vo Windows môžete použiť funkciu os.path.normcase(...), ak
ale chcete hľadať bez ohľadu na veľké/malé aj v Linuxe, tak vám normcase
nepomôže, streba použiť lower).
Skúste:
pocetprip("e:\\cv6",['.jpg','.jpeg'])
pocetprip("e:\\cv6",['.jpg','.BMP'])
Úloha 2:
Naprogramujte funkciu najhlbsi_subor(adresar), ktorá
nájde najhlbšie uložený súbor (teda ten, po ceste ku
ktorému je najviac adresárov, ak je takých súborov viac, tak stačí
nájsť jeden) a jeho hĺbku.
Hĺbku súboru počítame tak, že súbor uložený priamo v adresári
adresar má hĺbku 0.
Výsledok funkcie je dvojica:
(kompetná cesta k nájdenemu súboru, hĺbka nájdeného súboru)
Ak v celom podstrome adresar nie je žiadny súbor, tak má byť
výsledok ('',-1).
Úloha 3:
Naprogramujte funkciu triedenieFotiek(adresar_zdroj,
adresar_ciel), ktorý prejde celý podstrom začínajúci od
adresar_zdroj a prekopíruje z neho všetky súbory s príponou .jpg do
podadresárov adresar_ciel na základe ich času poslednej zmeny
tak, že v adresar_ciel vytvorí podadresáre pre roky (napr. 2010,
2012, 2016) a v nich podadresáre pre konkrétny deň v tvare rrmmdd
(napríklad 100913 pre fotky z 13. septembra 2010). Musí počítať s
tým, že niektoré podadresáre v adresar_ciel už existujú, niektoré
nie.
Dôležité: Kopírovanie súborov musí, zachovať ich dátum
poslednej modifikácie a čas posledného prístupu (to shutil.copyfile
nerobí, musíte to zabezpečiť skopírovaním dátumov pomocou
príslušných funkcií).
Skúste funkciu na adresári cv6\fotky.
Úloha 4:
Naprogramujte funkciu kopirujPodstrom(adresar_zdroj,adresar_ciel),
ktorý skopíruje celý podstrom adresárov a súborov začínajúci od
adresar_zdroj do adresar_ciel.
Napríklad kopirujPodstrom("d:\\cv6","e:\\cv6kopia")
vyrobí kópiu adresára d:\cv6 na inom disku e: a pomenuje ho
cv6kopia.
Navyše pri kopírovaní musí súborom zachovať čas poslednej
modifikácie a čas posledného prístupu (podobne ako v úlohe 3).
Naprogramujte aj test, či necheme kopírovať adresár do jeho
podadresára (asi by ste sa potom pri kopírovaní mohli zacykliť) a ak
áno, tak vyhláste chybu (vytvorte podtriedu Exception).
Dôležité: v Pythone nájdete funkciu, ktorá toto priamo robí,
ale účelom tejto úlohy nie je použiť hotovú funkciu z knižnice, ale
naprogramovať ju.