Python: compruebe si el archivo o directorio est谩 vac铆o

    Introducci贸n

    Python tiene un conjunto de funciones y objetos de biblioteca incorporados para ayudarnos con esta tarea. En este tutorial, aprenderemos c贸mo verificar si un archivo o directorio est谩 vac铆o en Python.

    Distinguir entre un archivo y un directorio

    Cuando nos gustar铆a comprobar si una ruta est谩 vac铆a o no, querremos saber si es un archivo o directorio, ya que esto afecta el enfoque que queremos utilizar.

    Digamos que tenemos dos variables de marcador de posici贸n dirpath y filepath identificando un directorio y archivo local:

    dirpath="/mnt/f/code.books/articles/python"
    filepath="/mnt/f/code.books/articles/python/code/file_dir.py"
    

    Usando os.path

    Python proporciona el os m贸dulo que es un paquete est谩ndar de Python de funciones, objetos y constantes para trabajar con el sistema operativo.

    os.path nos proporciona el isfile() y isdir() funciones para distinguir f谩cilmente entre un archivo y un directorio:

    import os
    
    dirpath="/mnt/f/code.books/articles/python"
    filepath="/mnt/f/code.books/articles/python/code/file_dir.py"
    
    os.path.isfile(dirpath) # False
    os.path.isdir(dirpath) # True
    os.path.isfile(filepath) # True
    os.path.isdir(filepath) # False
    

    Ambas funciones devuelven un Boolean valor.

    Usando pathlib

    Python 3.4 introdujo el pathlib m贸dulo, que proporciona una interfaz orientada a objetos para trabajar con los sistemas de archivos.

    pathlib simplifica el trabajo con sistemas de archivos en comparaci贸n con os o os.path.

    los Path clase de la pathlib El m贸dulo acepta una ruta como argumento y devuelve un Path objeto, que se puede consultar o encadenar f谩cilmente con m茅todos y atributos:

    from pathlib import Path
    
    dirpath="/mnt/f/code.books/articles/python"
    filepath="/mnt/f/code.books/articles/python/code/file_dir.py"
    
    Path(dirpath).is_file() # False
    Path(dirpath).is_dir() # True
    Path(filepath).is_file() # True
    Path(dirpath).is_file() # False
    

    Aqu铆, estamos comprobando si el Path en su lugar, el objeto es un archivo o directorio.

    Compruebe si un archivo est谩 vac铆o

    Un archivo vac铆o o un archivo de cero bytes es cualquier archivo que no contiene datos ni contenido. El archivo puede ser de cualquier tipo. Es posible que algunos archivos (como archivos de m煤sica) no tengan datos, pero a煤n contengan metadatos (como el autor). Estos archivos no se pueden considerar como un archivo vac铆o.

    Se puede crear un archivo vac铆o r谩pidamente en Linux y MacOS:

    $ touch emptyfile
    

    O en Windows:

    $ type nul > emptyfile
    

    Definamos variables ahora – emptyfile y nonemptyfile apuntando a un archivo vac铆o que tiene cero bytes y un archivo no vac铆o que tiene el tama帽o de un byte:

    emptyfile="/mnt/f/code.books/articles/python/emptyfile"
    nonemptyfile="/mnt/f/code.books/articles/python/onebytefile"
    

    Echemos un vistazo al tipo y tama帽o de estos archivos:

    $ ls -l
    -rwxrwxrwx 1 root root   0 Sep 10 18:06 emptyfile
    -rwxrwxrwx 1 root root   1 Sep 10 18:08 onebytefile
    $ file emptyfile
    emptyfile: empty
    $ file onebytefile
    onebytefile: very short file (no magic)
    

    Usando os.stat

    Alternativamente, podemos usar Python os m贸dulo para comprobar tambi茅n esta informaci贸n. los os.stat() la funci贸n devuelve un stat_result objeto. Este objeto es b谩sicamente una estructura de datos que es una colecci贸n de las propiedades del archivo:

    import os
    
    emptyfile="/mnt/f/code.books/articles/python/emptyfile"
    nonemptyfile="/mnt/f/code.books/articles/python/onebytefile"
    
    result = os.stat(nonemptyfile)
    result.st_size # 1
    
    result = os.stat(emptyfile)
    result.st_size # 0
    

    Usando os.path

    Python os.path El m贸dulo hace que sea muy f谩cil trabajar con rutas de archivo. Adem谩s de verificar la existencia de una ruta o distinguir su tipo, tambi茅n podemos recuperar el tama帽o de un archivo especificado como una cadena.

    os.path.getsize() devuelve el tama帽o de un archivo especificado como objeto similar a una ruta y es mucho m谩s f谩cil de usar que os.stat():

    import os
    
    emptyfile="/mnt/f/code.books/articles/python/emptyfile"
    nonemptyfile="/mnt/f/code.books/articles/python/onebytefile"
    
    os.path.getsize(emptyfile) # 0
    
    os.path.getsize(nonemptyfile) # 1
    

    Usando pathlib

    Si estamos trabajando en Python 3.4 o superior, podemos usar el pathlib m贸dulo para recuperar el tama帽o de un archivo. Esto b谩sicamente reemplaza el os m贸dulo. Path.stat() devuelve el stat_result propiedad de un Path objeto que es equivalente al valor de retorno de os.stat():

    from pathlib import Path
    
    emptyfile="/mnt/f/code.books/articles/python/emptyfile"
    nonemptyfile="/mnt/f/code.books/articles/python/onebytefile"
    
    print('File stats: ' + Path(emptyfile).stat())
    
    print('File size: ' + Path(emptyfile).stat().st_size + ' byte(s)')
    
    print('File stats: ' + Path(nonemptyfile).stat())
    
    print('File size: ' + Path(nonemptyfile).stat().st_size + ' byte(s)')
    

    Esto resulta en:

    File stats: os.stat_result(st_mode=33279, st_ino=14355223812249048, st_dev=17, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1600087010, st_mtime=1600087010, st_ctime=1600087010)
    File size: 0 byte(s)
    
    File stats: os.stat_result(st_mode=33279, st_ino=5629499534218713, st_dev=17, st_nlink=1, st_uid=0, st_gid=0, st_size=1, st_atime=1600088120, st_mtime=1600088072, st_ctime=1600088072)
    File size: 1 byte(s)
    

    Compruebe si un directorio est谩 vac铆o

    Un directorio que no contiene otros archivos o subdirectorios es un directorio vac铆o. Sin embargo, todos los directorios (incluso los vac铆os) contienen las siguientes 2 entradas:

    • . (punto pronunciado) hace referencia al directorio actual y es 煤til en operaciones como encontrar algo dentro del directorio actual
    • .. (punto doble pronunciado) hace referencia al directorio principal del directorio actual, es necesario retroceder desde el directorio actual

    Definamos dos variables: emptydirectory y nonemptydirectory apuntando a un directorio vac铆o y no vac铆o:

    emptydirectory = '/mnt/f/code.books/articles/python/markdown'
    nonemptydirectory = '/mnt/f/code.books/articles/python/code'
    

    El directorio vac铆o no tiene ning煤n elemento en 茅l:

    $ pwd
    /mnt/f/code.books/articles/python/markdown
    $ ls -la
    total 0
    drwxrwxrwx 1 root root 512 Sep 11 11:52 .
    drwxrwxrwx 1 root root 512 Sep 10 20:22 ..
    

    El directorio no vac铆o tiene un solo archivo:

    $ pwd
    /mnt/f/code.books/articles/python/code
    $ ls -la
    total 0
    drwxrwxrwx 1 root root 512 Sep 14 11:02 .
    drwxrwxrwx 1 root root 512 Sep 14 18:22 ..
    -rwxrwxrwx 1 root root 425 Sep 14 12:27 file_dir.py
    

    Usando os.listdir ()

    los os.listdir() devuelve una secuencia que contiene el nombre de todos los elementos encontrados en la ruta del directorio pasada como argumento. No incluye el . y .. entradas:

    import os
    
    os.listdir(emptydirectory) # []
    os.listdir(nonemptydirectory) # ['file_dir.py']
    

    El c谩lculo de la longitud de la lista devuelta determina f谩cilmente si el directorio est谩 vac铆o o no. Un directorio vac铆o siempre tiene una longitud de cero:

    import os
    
    print(len(os.listdir(nonemptydirectory))) # 1
    print(len(os.listdir(emptydirectory))) # 0
    

    Usando os.scandir ()

    los os.listdir() La funci贸n es 煤til cuando necesita un mont贸n de nombres de entradas como lista para su posterior procesamiento. Sin embargo, para comprobar si hay al menos una entrada 煤nica, no necesitamos una lista de todos los archivos que contiene.

    Si un directorio es enorme, el os.listdir() La funci贸n tardar谩 mucho en ejecutarse, mientras que, siempre que haya m谩s de 0 entradas, nuestra pregunta est谩 respondida.

    Una funci贸n que viene en ayuda es os.scandir() que devuelve un iterable o generador perezoso.

    Los generadores devuelven iteradores que se pueden recorrer como iterables normales, como una lista. Pero a diferencia de una lista, conjunto o diccionario, no almacenan una gran cantidad de valores en la memoria y en su lugar devuelven un nuevo valor a pedido.

    Este enfoque es aproximadamente ~ 200 veces m谩s r谩pido en directorios de ~ 1000 archivos.

    Entonces, en lugar de recorrer toda la estructura del directorio, podemos usar os.scandir() para comprobar si hay al menos una entrada encontrada en la ruta del directorio:

    import os
    
    emptydirectory = '/mnt/f/code.books/articles/python/markdown'
    nonemptydirectory = '/mnt/f/code.books/articles/python/code'
    
    print(next(os.scandir(emptydirectory), None))
    print(next(os.scandir(nonemptydirectory), None)) # <DirEntry 'file_dir.py'>
    

    Estamos usando next() que es una funci贸n incorporada para recuperar el siguiente elemento disponible del iterador perezoso devuelto por os.scandir(). Ya que emptydirectory no tiene art铆culos disponibles – est谩 regresando None mientras que para nonemptydirectory est谩 devolviendo un os.DirEntry objeto.

    Usando pathlib

    Un enfoque preferido para os m贸dulo es el pathlib m贸dulo. Usaremos pathlib.Path.iterdir(), que no solo es m谩s simple sino tambi茅n mucho m谩s f谩cil de usar que os.listdir() o os.scandir().

    Devuelve un objeto iterable o generador perezoso muy parecido a os.scandir(), que itera sobre los archivos en la ruta del directorio pasada como argumento:

    from pathlib import Path
    print(Path(emptydirectory).iterdir()) # <generator object Path.iterdir at 0x7f2cf6f584a0>
    

    Utilizando next(), estamos intentando recuperar el siguiente art铆culo disponible. Con None como art铆culo de devoluci贸n predeterminado, next() no levantar谩 un StopIteration excepci贸n en caso de que no haya ning煤n art铆culo en la colecci贸n:

    print(next(Path(emptydirectory).iterdir(), None)) # None
    print(next(Path(nonemptydirectory).iterdir(), None)) # /mnt/f/code.books/articles/python/code/file_dir.py
    

    La mayor铆a de las funciones integradas de Python funcionan con iterables, incluida la funci贸n any () que devuelve True si el iterable tiene al menos un elemento que se puede evaluar como True:

    from pathlib import Path
    print(any(Path(emptydirectory).iterdir()) # False
    print(any(nonemptydirectory).iterdir()) # True
    

    Conclusi贸n

    En este tutorial, hemos repasado c贸mo distinguir entre archivos y directorios, luego de lo cual verificamos su vac铆o.

    Esto se puede hacer a trav茅s del os o pathlib m贸dulos y sus funciones y clases de conveniencia.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *