2008-09-09 29 views
61

Necesito una forma de determinar el espacio restante en un volumen de disco usando python en linux, Windows y OS X. Actualmente estoy analizando el resultado de varias llamadas al sistema (df, dir) para lograr esto, ¿hay una mejor manera?Espacio multiplataforma restante en el volumen usando python

+1

Ver esta receta aquí: http://code.activestate.com/recipes/577972-disk-usage/?in=user-4178764 –

Respuesta

2

La función os.statvfs() es una mejor manera de obtener esa información para plataformas tipo Unix (incluido OS X). La documentación de Python dice "Disponibilidad: Unix", pero vale la pena comprobar si también funciona en Windows en tu compilación de Python (es decir, es posible que los documentos no estén actualizados).

De lo contrario, puede usar la biblioteca pywin32 para llamar directamente a la función GetDiskFreeSpaceEx.

+2

os.statvfs() no funciona en Windows (Python 2.5.2 - versión de producción actual). – jfs

+2

no plataforma cruzada – pufferfish

0

I No conozco ninguna forma de plataforma cruzada para lograr esto, pero tal vez una buena solución para usted sería escribir una clase contenedora que verifique el sistema operativo y use el mejor método para cada una.

Para Windows, existe el método GetDiskFreeSpaceEx en las extensiones de win32.

2

Puede usar df de forma multiplataforma. Es una parte de GNU core utilities. Estas son las utilidades principales que se espera que existan en todos los sistemas operativos. Sin embargo, no están instalados en Windows por defecto (Aquí, GetGnuWin32 es útil).

df es una utilidad de línea de comandos, por lo tanto, se necesita un contenedor para la creación de scripts. Por ejemplo:

from subprocess import PIPE, Popen 

def free_volume(filename): 
    """Find amount of disk space available to the current user (in bytes) 
     on the file system containing filename.""" 
    stats = Popen(["df", "-Pk", filename], stdout=PIPE).communicate()[0] 
    return int(stats.splitlines()[1].split()[3]) * 1024 
+4

No entiendo por qué las personas votaron negativamente. Por ejemplo, esta respuesta puede ser útil para alguien. De todos modos, es un buen complemento para las otras soluciones puto-Pythonic. Si a alguien no le gusta la respuesta, no hay razón para rechazarla. Según entiendo, los downvotes son para respuestas francamente incorrectas. Este no es – ovgolovin

+0

@ovgolovin Hasta vote esta respuesta y es bueno saber otra manera de hacer lo mismo. – Erxin

5

si no te gusta añadir otra dependencia que pueda para ventanas utilizan ctypes a llamar a la llamada a la función Win32 directamente.

import ctypes 

free_bytes = ctypes.c_ulonglong(0) 

ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(u'c:\\'), None, None, ctypes.pointer(free_bytes)) 

if free_bytes.value == 0: 
    print 'dont panic' 
+2

plataforma cruzada ?? – pufferfish

65
import ctypes 
import os 
import platform 
import sys 

def get_free_space_mb(dirname): 
    """Return folder/drive free space (in megabytes).""" 
    if platform.system() == 'Windows': 
     free_bytes = ctypes.c_ulonglong(0) 
     ctypes.windll.kernel32.GetDiskFreeSpaceExW(ctypes.c_wchar_p(dirname), None, None, ctypes.pointer(free_bytes)) 
     return free_bytes.value/1024/1024 
    else: 
     st = os.statvfs(dirname) 
     return st.f_bavail * st.f_frsize/1024/1024 

Tenga en cuenta que debe pasar un nombre de directorio para GetDiskFreeSpaceEx() para trabajar (statvfs() funciona tanto en archivos y directorios). Puede obtener un nombre de directorio desde un archivo con os.path.dirname().

Consulte también la documentación para os.statvfs() y GetDiskFreeSpaceEx.

+13

'.f_bfree' es la cantidad total de bloques libres en el sistema de archivos. Se debe multiplicar por '.f_bsize' para obtener el número de bytes. – jfs

+8

Al menos en OS X Lion/Python 2.7 Noté que multiplicar por '.f_bsize' da un valor demasiado grande ya que' f_bsize' es el tamaño de bloque * preferred * mientras que '.f_frsize' es el tamaño de bloque * fundamental * y da el valor correcto En mi sistema de prueba de Linux, ambos valores son idénticos y, por lo tanto, '.f_frsize' debería funcionar todo el tiempo. –

+1

Funciona para obtener el disco disponible en el teléfono Android, conectado a través de USB a un sistema Windows, ejecutando el script en Windows. Estupendo. – heltonbiker

5

Una buena forma de plataforma cruzada es usar psutil: http://pythonhosted.org/psutil/#disks (Tenga en cuenta que necesitará psutil 0.3.0 o superior).

+0

Esta sería la mejor respuesta, pero lamentablemente no se puede instalar psutil a través de pip. –

+1

psutil ya está disponible en pypi y en la mayoría de las otras fuentes, incluidos los paquetes Debian. – Tully

17

podría utilizar el módulo de wmi para ventanas y os.statvfs para UNIX

para la ventana

import wmi 

c = wmi.WMI() 
for d in c.Win32_LogicalDisk(): 
    print(d.Caption, d.FreeSpace, d.Size, d.DriveType) 

para UNIX o Linux

from os import statvfs 

statvfs(path) 
+1

No puedo creer lo lejos que tuve que hacer esta pregunta para encontrar a alguien que mencionara el WMI. ¿Todos estos locos usan ctypes para llamar directamente a las API de Windows C cuando simplemente pueden usar el WMI? –

+0

@CraigRinger Sí, tienes razón. Deberíamos usar la herramienta adecuada para hacer lo correcto. La mayoría de las tareas de administración comunes para Windows ya se han completado con win api in wmi. No tenemos que rehacer la rueda. :^D – Erxin

+0

¿Por qué no lo maneja 'psutil'? – Fr0zenFyr

13

Instalar psutil usando pip install psutil.Entonces se puede obtener la cantidad de espacio libre en bytes usando:

import psutil 
print(psutil.disk_usage(".").free) 
+0

¿Por qué esta no es la mejor respuesta? – jayatubi

+0

Creo que porque psutil no siempre estaba disponible a través de pypi. – jhasse

1

A continuación código devuelve valor correcto en las ventanas

import win32file  

def get_free_space(dirname): 
    secsPerClus, bytesPerSec, nFreeClus, totClus = win32file.GetDiskFreeSpace(dirname) 
    return secsPerClus * bytesPerSec * nFreeClus 
0

Si está ejecutando python3:

Usando shutil.disk_usage() con os.path.realpath('/') nombre-regularización de obras:

from os import path 
from shutil import disk_usage 

print([i/1000000 for i in disk_usage(path.realpath('/'))]) 

O

total_bytes, used_bytes, free_bytes = disk_usage(path.realpath('D:\\Users\\phannypack')) 

print(total_bytes/1000000) # for Mb 
print(used_bytes/1000000) 
print(free_bytes/1000000) 

dándole total, utilizado, & espacio libre en MB.

Cuestiones relacionadas