Plattformübergreifender Speicherplatz, der mit Python auf dem Volume verbleibt

Antworten:

74
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

Beachten Sie, dass Sie einen Verzeichnisnamen übergeben müssenGetDiskFreeSpaceEx() , damit dies funktioniert ( statvfs()funktioniert sowohl für Dateien als auch für Verzeichnisse). Sie können einen Verzeichnisnamen aus einer Datei mit abrufen os.path.dirname().

Siehe auch die Dokumentation zu os.statvfs()und GetDiskFreeSpaceEx.

Frankovskyi Bogdan
quelle
13
.f_bfreeist die Gesamtzahl der freien Blöcke im Dateisystem. Es sollte mit multipliziert werden .f_bsize, um die Anzahl der Bytes zu erhalten.
JFS
8
Zumindest unter OS X Lion / Python 2.7 ist mir aufgefallen, dass das Multiplizieren mit .f_bsizeeinen viel zu großen Wert ergibt, ebenso f_bsizewie die bevorzugte Blockgröße, während .f_frsizedie grundlegende Blockgröße und der richtige Wert sind. Auf meinem Linux-Testsystem sind beide Werte identisch und .f_frsizesollten daher immer funktionieren.
Dennis Bliefernicht
1
Funktioniert, um verfügbare Festplatten auf Android Phone zu erhalten, die über USB an ein Windows-System angeschlossen sind und das Skript unter Windows ausführen. Toll.
Heltonbiker
@JFSebastian Es kommt darauf an, was Sie wollen. Linux kann Speicherplatz für root reservieren. Wenn Sie diesen Bereich einschließen möchten, verwenden Sie f_bfree. Wenn Sie die Anzahl der Blöcke ermitteln möchten, die einem Benutzer zur Verfügung stehen, verwenden Sie f_bavail. Vielleicht kann jemand sagen, ob und wie Quoten behandelt werden?
Daten
Ich habe drei Probleme mit dem oben Gesagten: 1 / Die Dokumentzeichenfolge ist falsch, sie gibt Speicherplatz in MByte zurück & 2 / Ich mag es nie, mehr als eine return-Anweisung zu sehen (ich denke, zu viel Zeit als Tester), also würde ich das Ergebnis in a speichern Der zurückgegebene Wert 3 / Gesamt-MB oder Dezimal-MB kann für einige Personen einen Unterschied bedeuten.
Steve Barnes
28

Installieren Sie psutil mit pip install psutil. Dann können Sie die Menge an freiem Speicherplatz in Bytes ermitteln, indem Sie:

import psutil
print(psutil.disk_usage(".").free)
jhasse
quelle
2
Warum ist das nicht die beste Antwort?
Jayatubi
2
Ich denke, weil Psutil nicht immer über Pypi erhältlich war.
jhasse
Ich stimme dem eine großartige Antwort zu. Ich habe den veralteten Link zu behoben psutil. Da disk_usage.freenormalerweise eine große 64b-Ganzzahl zurückgegeben wird, sollten Sie auch Personen anzeigen disk_usage.percent. psutil.disk_usage(".").percent < 99.9scheint mir klarer ...
smci
24

Sie können das wmi- Modul für Windows und os.statvfs für Unix verwenden

für Fenster

import wmi

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

für Unix oder Linux

from os import statvfs

statvfs(path)
Erxin
quelle
1
Ich kann nicht glauben, wie weit ich diese Frage gehen musste, um jemanden zu finden, der das WMI erwähnt. All diese verrückten Leute, die ctypes verwenden, um Windows C-APIs direkt aufzurufen, wenn sie nur die WMI verwenden könnten?
Craig Ringer
@CraigRinger Ja, du hast recht. Wir sollten das richtige Werkzeug verwenden, um das Richtige zu tun. Die meisten gängigen Verwaltungsaufgaben für Fenster wurden bereits mit win api in wmi abgeschlossen. Wir müssen das Rad nicht neu machen. : ^ D
Erxin
Warum nicht damit psutilumgehen?
Fr0zenFyr
1
Deshalb liebe ich Stackoverflow. Ich wusste nicht einmal über das WMI-Modul Bescheid und es funktionierte einwandfrei.
DanGoodrick
@ Fr0zenFyr ja, das ist eine weitere gute Option für diese Aufgabe.
Erxin
11

Wenn Sie python3 ausführen:

Verwendung shutil.disk_usage()mit os.path.realpath('/')Namensregulierung funktioniert:

from os import path
from shutil import disk_usage

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

Oder

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)

Geben Sie den gesamten, verwendeten und freien Speicherplatz in MB an.

Rob Truxal
quelle
8

Wenn Sie keine weitere Abhängigkeit hinzufügen möchten, können Sie für Windows ctypes verwenden, um den Funktionsaufruf win32 direkt aufzurufen.

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'
Stefan Lundström
quelle
5

Eine gute plattformübergreifende Methode ist die Verwendung von psutil: http://pythonhosted.org/psutil/#disks (Beachten Sie, dass Sie psutil 0.3.0 oder höher benötigen).

Yuriy
quelle
Dies wäre die beste Antwort, aber leider kann psutil nicht über pip installiert werden.
Gringo Suave
1
psutil ist jetzt bei pypi und den meisten anderen Quellen erhältlich, einschließlich Debian-Paketen.
Tully
3

Sie können df plattformübergreifend verwenden. Es ist Teil der GNU-Kerndienstprogramme . Dies sind die Kerndienstprogramme, die auf jedem Betriebssystem vorhanden sein sollen. Sie werden jedoch standardmäßig nicht unter Windows installiert (hier ist GetGnuWin32 nützlich).

df ist ein Befehlszeilenprogramm, daher ein Wrapper, der für Skriptzwecke benötigt wird. Zum Beispiel:

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
jfs
quelle
4
Ich verstehe nicht, warum die Leute abstimmen. Zum Beispiel kann diese Antwort für jemanden nützlich sein. Auf jeden Fall ist es eine gute Ergänzung für die anderen puppenpythonischen Lösungen. Wenn jemand die Antwort nicht mag, gibt es keinen Grund, sie abzulehnen. Nach meinem Verständnis sind Abstimmungen für geradezu falsche Antworten. Dieser ist nicht.
Ovgolovin
@ovgolovin Stimmen Sie diese Antwort ab und es ist gut, einen anderen Weg zu kennen, um das Gleiche zu tun.
Erxin
1

Der folgende Code gibt unter Windows den korrekten Wert zurück

import win32file    

def get_free_space(dirname):
    secsPerClus, bytesPerSec, nFreeClus, totClus = win32file.GetDiskFreeSpace(dirname)
    return secsPerClus * bytesPerSec * nFreeClus
Sanjay Bhosale
quelle
1

Die Funktion os.statvfs () ist eine bessere Möglichkeit, diese Informationen für Unix-ähnliche Plattformen (einschließlich OS X) abzurufen . In der Python-Dokumentation steht "Verfügbarkeit: Unix", es lohnt sich jedoch zu prüfen, ob es auch in Ihrem Python-Build unter Windows funktioniert (dh die Dokumente sind möglicherweise nicht auf dem neuesten Stand).

Andernfalls können Sie die pywin32- Bibliothek verwenden, um die GetDiskFreeSpaceEx- Funktion direkt aufzurufen .

Greg Hewgill
quelle
3
os.statvfs () funktioniert nicht unter Windows (Python 2.5.2 - aktuelle Produktionsversion).
JFS
0

Ich kenne keinen plattformübergreifenden Weg, um dies zu erreichen, aber vielleicht wäre eine gute Problemumgehung für Sie, eine Wrapper-Klasse zu schreiben, die das Betriebssystem überprüft und für jede die beste Methode verwendet.

Für Windows gibt es die GetDiskFreeSpaceEx- Methode in den win32-Erweiterungen.

Hasseg
quelle