Python: compruebe si el archivo o directorio está vacío

P

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.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad