2008-09-09 18 views
61

J'ai besoin d'un moyen de déterminer l'espace restant sur un volume de disque en utilisant python sous Linux, Windows et OS X. J'analyse actuellement la sortie des divers appels système (df, dir) pour accomplir ceci - y a-t-il un meilleur moyen?Espace multiplate-forme restant sur le volume en utilisant python

+1

Voir cette recette ici: http://code.activestate.com/recipes/577972-disk-usage/?in=user-4178764 –

Répondre

2

La fonction os.statvfs() est une meilleure façon d'obtenir cette information pour les plateformes de type Unix (y compris OS X). La documentation Python indique "Disponibilité: Unix" mais il vaut la peine de vérifier si cela fonctionne aussi sous Windows dans votre version de Python (c'est-à-dire que les docs ne sont peut-être pas à jour). Sinon, vous pouvez utiliser la bibliothèque pywin32 pour appeler directement la fonction GetDiskFreeSpaceEx.

+2

os.statvfs() ne fonctionne pas sous Windows (Python 2.5.2 - version de production actuelle). – jfs

+2

pas cross plate-forme – pufferfish

0

I Je ne connais pas de méthode multiplateforme pour y parvenir, mais une bonne solution consiste à écrire une classe wrapper qui vérifie le système d'exploitation et utilise la meilleure méthode pour chacun.

Pour Windows, il existe la méthode GetDiskFreeSpaceEx dans les extensions win32.

2

Vous pouvez utiliser df comme mode multiplateforme. C'est une partie de GNU core utilities. Ce sont les utilitaires de base qui devraient exister sur chaque système d'exploitation. Cependant, ils ne sont pas installés sur Windows par défaut (ici, GetGnuWin32 est pratique).

df est un utilitaire de ligne de commande, donc un wrapper requis pour les scripts. Par exemple:

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

Je ne comprends pas pourquoi les gens downvote. Par exemple, cette réponse peut être utile à quelqu'un. En tout cas c'est un bon complément pour les autres solutions pupe-Pythonic. Si quelqu'un n'aime pas la réponse, il n'y a aucune raison de la réduire. Si je comprends bien, les downvotes sont carrément fausses réponses. Celui-ci n'est pas. – ovgolovin

+0

@ovgolovin Votez pour cette réponse et il est bon de savoir une autre façon de faire la même chose. – Erxin

5

Si vous ne souhaitez ajouter une autre dépendance, vous pouvez utiliser pour Windows ctypes pour appeler l'appel de fonction win32 directement.

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

plateforme croisée ?? – 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 

Notez que vous devez passer un nom de répertoire pour GetDiskFreeSpaceEx() travailler (statvfs() travaux sur les fichiers et répertoires). Vous pouvez obtenir un nom de répertoire à partir d'un fichier avec os.path.dirname(). Voir aussi la documentation pour os.statvfs() et GetDiskFreeSpaceEx.

+13

'.f_bfree' est le nombre total de blocs libres dans le système de fichiers. Il devrait être multiplié par '.f_bsize' pour obtenir le nombre d'octets. – jfs

+8

Au moins sur OS X Lion/Python 2.7 J'ai remarqué que multiplier par '.f_bsize' donne une valeur beaucoup trop grande car' f_bsize' est la taille de bloc * preferred * alors que '.f_frsize' est la taille de bloc * fondamentale * et donne la valeur correcte. Sur mon système de test Linux, les deux valeurs sont identiques et donc '.f_frsize' devrait fonctionner tout le temps. –

+1

Fonctionne pour obtenir le disque disponible sur Android Phone, branché via USB à un système Windows, exécutant le script sur Windows. Génial. – heltonbiker

5

Une bonne méthode multi-plateforme utilise psutil: http://pythonhosted.org/psutil/#disks (Notez que vous aurez besoin de psutil 0.3.0 ou supérieur).

+0

Ce serait la meilleure réponse, mais malheureusement psutil n'est pas installable via pip. –

+1

psutil est maintenant disponible à partir de pypi et de la plupart des autres sources, y compris les paquets debian. – Tully

17

Vous pouvez utiliser le module wmi pour les fenêtres et os.statvfs pour unix

pour fenêtre

import wmi 

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

pour linux ou unix

from os import statvfs 

statvfs(path) 
+1

Je ne peux pas croire jusqu'où j'ai dû descendre cette question pour trouver quelqu'un mentionnant le WMI. Tous ces fous utilisant des ctypes pour appeler les API de Windows C directement quand ils pourraient simplement utiliser le WMI? –

+0

@CraigRinger Oui, vous avez raison. Nous devrions utiliser le bon outil pour faire la bonne chose. La plupart des tâches de gestion communes pour window ont déjà été emballées avec win api dans wmi. Nous n'avons pas à refaire la roue. :^D – Erxin

+0

Pourquoi pas "psutil" le gérer? – Fr0zenFyr

13

Installation psutil à l'aide pip install psutil.Ensuite, vous pouvez obtenir la quantité d'espace libre en octets en utilisant:

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

Pourquoi ce n'est pas la meilleure réponse? – jayatubi

+0

Je pense que parce que psutil n'était pas toujours disponible via pypi. – jhasse

1

Ci-dessous le code renvoie la valeur correcte sur les fenêtres

import win32file  

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

Si vous utilisez python3:

en utilisant shutil.disk_usage() avec os.path.realpath('/') œuvres nom régularisation:

from os import path 
from shutil import disk_usage 

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

Ou

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) 

vous donnant le total, utilisé, & espace libre MB.

Questions connexes