Како проверити величину датотеке и фасцикле у Питхон-у?

Analiza veličine datoteka i direktorijuma pomoću Pythona

U ovom tekstu istražićemo kako u Pythonu možemo utvrditi veličinu pojedinačnih datoteka, kao i čitavih direktorijuma.

Python je izuzetno fleksibilan programski jezik. Njegova primenljivost proteže se od kreiranja jednostavnih alata u komandnoj liniji do razvoja kompleksnih web aplikacija.

Ipak, često zanemarena prednost Pythona je njegova sposobnost da interreaguje sa operativnim sistemima. Korišćenje Pythona za upravljanje operacijama OS-a može značajno ubrzati procese automatizacije.

Pogledajmo sada kako Python komunicira sa operativnim sistemom.

Kako Python ostvaruje komunikaciju sa operativnim sistemom?

Nemoguće je funkcionisati izolovano od okoline, a to važi i za Python. U mnogim situacijama, interakcija sa operativnim sistemom je ključna za obavljanje zadataka.

Python nudi nekoliko modula koji omogućavaju ovu interakciju. Najčešće korišćeni su os, sys, pathlib i subprocess.

Pošto se radi o ugrađenim modulima, nema potrebe za njihovom instalacijom putem PIP-a. Jednostavno ih možete uvesti koristeći sledeću naredbu:

import os
import sys
import pathlib
import subprocess

U nastavku je dat pregled osnovnih funkcija svakog od navedenih modula:

  • os: Pruža prenosiv način korišćenja funkcionalnosti specifične za operativni sistem. Idealno rešenje u većini slučajeva, osim kada su potrebne naprednije opcije.
  • sys: Omogućava pristup parametrima i funkcijama samog Python interpretatora. Dok os modul komunicira sa operativnim sistemom, sys radi sa Python interpretatorom.
  • pathlib: Namenjen za napredno rukovanje putanjama. Omogućava predstavljanje sistema datoteka kao objekata, uz odgovarajuću semantiku za svaki operativni sistem.
  • subprocess: Služi za pokretanje i kontrolu podprocesa direktno iz Pythona, uključujući rad sa standardnim ulazom, izlazom i povratnim kodovima. Detaljnije informacije možete pronaći u našem vodiču za podprocese u Pythonu.

Postoje i biblioteke višeg nivoa koje nude još specifičnije funkcionalnosti, zavisno od potreba. Ipak, u većini slučajeva, navedeni moduli su dovoljni.

Napomena: Funkcije koje ovi moduli pružaju mogu imati različite rezultate u zavisnosti od operativnog sistema. Imajte na umu da Python najbolje funkcioniše sa UNIX sistemima.

Sada kada razumemo kako Python komunicira sa OS-om, pređimo na metode za određivanje veličine datoteka i direktorijuma. Sva rešenja su dostupna u File-and-folder-size-in-Python GitHub repozitorijumu.

Korišćenje os.stat().st_size

U ovoj metodi ćemo koristiti funkciju stat() iz os modula. Ova funkcija vraća brojne informacije o specificiranoj putanji.

Napomena: Funkcija os.path.getsize() takođe može obaviti isti posao, ali prednost korišćenja os.stat().st_size je u tome što ne prati simlinkove.

Pre nego što nastavimo, kreirajmo probnu datoteku pod nazivom lorem.txt i u nju ubacimo neki probni tekst. Možete posetiti Lorem Ipsum generator i kopirati tekst u lorem.txt.

U istom direktorijumu kreirajte datoteku method1.py i dodajte sledeći kod:

import os
size = os.stat('lorem.txt').st_size
print(size)

Analizirajmo kod:

  • U prvom redu uvozimo os modul.
  • Varijabla size sadrži veličinu datoteke lorem.txt
    • Funkcija os.stat() vraća skup informacija o datoteci.
    • Atribut st_size predstavlja veličinu datoteke.
  • Štampamo varijablu size.

Pokrenite Python skriptu. Dobićete različit rezultat u zavisnosti od sadržaja vaše datoteke lorem.txt.

Izlaz:

20064

Izlaz je predstavljen u bajtovima, što nije baš pregledno. Zato ćemo ga humanizovati kako bismo dobili bolji uvid u veličinu datoteke.

Prvo instalirajte humanize paket, koristeći sledeću komandu u terminalu:

pip install humanize

Zatim možete koristiti funkciju naturalsize() koja konvertuje veličinu u bajtovima u format čitljiv za ljude, na primer, KB, MB, GB ili TB.

import os
from humanize import naturalsize

size = os.stat('lorem.txt').st_size

print(size)
print(naturalsize(size))

Gornji kod prvo prikazuje veličinu datoteke u bajtovima, a zatim rezultat u čitljivom formatu.

Izlaz:

20064
20.1 kB

Korišćenje Pathlib-a

Pathlib je dizajniran za rad sa putanjama, ali uključuje i korisne funkcije iz drugih modula kao metode Path objekata (instanci klase Path).

Kreirajte datoteku method2.py i uvezite klasu Path.

from pathlib import Path

Zatim kreirajte Path objekat, prosleđujući putanju do datoteke lorem.txt kao argument.

file_ = Path('lorem.txt')

Sada možete pristupiti metodi stat() klase Path, koja radi isto kao i funkcija os.stat(). Na taj način možete prikazati veličinu datoteke.

print(file_.stat().st_size)

Izlaz:

20064

Kao što vidite, dobijamo isti rezultat kao u prvom metodu. Gore navedeni rezultat je takođe u bajtovima, pa koristimo modul humanize kako bismo ga učinili čitljivim.

from pathlib import Path
from humanize import naturalsize

size = Path('lorem.txt').stat().st_size

print(naturalsize(size))

Ovaj kod generiše sledeći izlaz:

20.1 kB

Korišćenje Unix komandi putem subprocess-a

Modul subprocess omogućava pozivanje i upravljanje podprocesima iz Pythona. Stoga, možemo izvršiti bilo koju komandu i njen izlaz obraditi direktno u Pythonu.

Napomena: Ova metoda radi samo na UNIX operativnim sistemima (Linux, Mac).

Otvorite datoteku method3.py i unesite sledeći kod:

from subprocess import run

process = run(['du', 'lorem.txt'], capture_output=True, text=True)

print(process.stdout)

Hajde da analiziramo ovaj kod:

  • Uvozimo funkciju run iz modula subprocess.
  • Varijabla process sadrži rezultat izvršenja komande du lorem.txt.
    • du je Linux uslužni program za prikazivanje prostora na disku datoteke.
    • capture_output omogućava pristup standardnom izlazu.
    • text znači da čuvamo izlaz kao string umesto bajtova.
  • Štampamo standardni izlaz procesa.

Ako pokrenete gornji kod, dobićete sledeći izlaz:

20      lorem.txt

Kao što vidite, izlaz sadrži veličinu i ime datoteke. Ako želite da dobijete samo veličinu datoteke, morate podeliti izlaz (zapamtite da je to string) i prikazati prvi element.

from subprocess import run

process = run(['du', 'lorem.txt'], capture_output=True, text=True)

size = process.stdout.split()[0]

print(size)

Izlaz:

20

Ovaj izlaz nije baš čitljiv. Možemo pretpostaviti da je merna jedinica KB (na osnovu prethodnih metoda), ali bez toga bi veličina datoteke bila teška za procenu.

Da bismo rešili ovaj problem, možemo koristiti -h (human-readable) zastavicu.

Napomena: Uputstvo za ovu komandu možete dobiti izvršavanjem komande man du ili du –help.

from subprocess import run

process = run(['du', '-h', 'lorem.txt'], capture_output=True, text=True)

size = process.stdout.split()[0]

print(size)

Sada će izlaz ove skripte biti mnogo čitljiviji:

20K

Za više informacija o modulu subprocess i njegovim potencijalnim primenama, pogledajte naš vodič o podprocesima u Pythonu.

Rekurzivno dobijanje veličine direktorijuma

Ako želite da dobijete veličinu direktorijuma, morate proći kroz svaku datoteku u datom direktorijumu i svim njegovim poddirektorijumima. Uradićemo to na dva načina:

  • Iteracijom preko putanje sa pathlib
  • Korišćenjem komande du sa subprocess

Sledeći kod će koristiti putanju do test direktorijuma unutar mog početnog direktorijuma. Morate promeniti putanju do direktorijuma čiju veličinu želite da izračunate.

Iteracija kroz putanju sa pathlib

Pogledajmo kako možete dobiti veličinu direktorijuma iteriranjem kroz veličine pojedinačnih datoteka.

from pathlib import Path
from humanize import naturalsize

def get_size(path="."):
    size = 0

    for file_ in Path(path).rglob('*'):

        size += file_.stat().st_size
    
    return naturalsize(size)

test_path = Path.home() / 'Documents/tests/'

print(get_size(test_path))

Ovaj deo koda izgleda malo zastrašujuće, pa hajde da analiziramo šta svaki njegov deo radi.

  • Uvozimo klasu Path i funkciju naturalsize().
  • Definišemo funkciju get_size() sa parametrom path, koji po defaultu pokazuje na trenutni direktorijum.
  • Varijabla size je čuvar mesta u koju ćemo dodavati veličinu svake datoteke.
  • Iteriramo kroz svaku datoteku putanje.
  • Dobijamo veličinu svake datoteke i dodajemo je varijabli size.
  • Vraćamo varijablu size u čitljivom formatu.

Naravno, testiram funkciju sa direktorijumom koji je dostupan samo na mojoj mašini. Ne zaboravite da promenite putanju do direktorijuma koji postoji na vašem računaru.

U mom slučaju, dobijam sledeći izlaz:

403.4 MB

Korišćenje komande du sa subprocess

Ovaj pristup ima nekoliko prednosti:

  • Rezultat je malo precizniji.
  • Mnogo je brži.
from subprocess import run
from pathlib import Path

test_path = Path.home() / 'Documents/tests/'

process = run(['du', '-sh', test_path], capture_output=True, text=True)

size = process.stdout.split()[0]

print(size)

Koristimo isti pristup kao u metodu 3, ali ovog puta dobijamo veličinu direktorijuma umesto datoteke.

Izlaz:

481M

Kao što vidite, ova dva načina za dobijanje veličine direktorijuma daju malo različite rezultate. Što je veći direktorijum, razlika u rezultatu će biti veća.

Na vama je da izaberete između pathlib ili subprocess pristupa. Ako znate da ćete uvek koristiti Linux, možete koristiti subprocess, inače je bolje koristiti rešenje sa pathlib.

Zaključak

Python je izuzetno koristan za interakciju sa operativnim sistemom. Možete automatizovati procese i uštedeti mnogo vremena uz Python. Glavni moduli za interakciju sa operativnim sistemom su os, sys, pathlib i subprocess.

U ovom vodiču naučili ste:

  • Kako Python komunicira sa OS-om.
  • Kako koristiti ugrađene module za obavljanje OS operacija.
  • Kako koristiti humanize modul za prikazivanje čitljivog izlaza.
  • Kako izračunati veličinu datoteke pomoću tri pristupa.
  • Kako izračunati veličinu direktorijuma rekurzivno ili pomoću komande du.