파이썬을 사용하여 디렉토리의 크기를 계산합니까?


181

이 특정 바퀴를 다시 발명하기 전에 파이썬을 사용하여 디렉토리의 크기를 계산하는 데 좋은 루틴을 가진 사람이 있습니까? 루틴이 크기를 Mb / Gb 등으로 멋지게 포맷하면 매우 좋을 것입니다.


13
아주 좋지 않을 것입니다. 크기를 계산하는 하나의 함수와 "Mb / Gb 등으로 크기를 멋지게 형식화"하는 매우 독립적 인 함수 (예 : 메모리 크기와 함께 사용할 수 있음)가 있어야합니다.
John Machin

17
예, 알고 있지만 두 가지 질문을 저장합니다.
게리 윌로우 비

1
tree* nix 시스템 의 명령은이 모든 것을 무료로 수행합니다. tree -h -d --du /path/to/dir.
meh

@mehdu -sh /path/to/dir/*
mrgloom

답변:


251

이것은 모든 하위 디렉토리를 걷는다; 합산 파일 크기 :

import os

def get_size(start_path = '.'):
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(start_path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            # skip if it is symbolic link
            if not os.path.islink(fp):
                total_size += os.path.getsize(fp)

    return total_size

print(get_size(), 'bytes')

os.listdir을 사용하는 재미를위한 oneliner ( 하위 디렉토리는 포함하지 않음 ) :

import os
sum(os.path.getsize(f) for f in os.listdir('.') if os.path.isfile(f))

참고:

업데이트 사용에 os.path.getsize , 이것은 os.stat (). st_size 방법을 사용하는 것보다 더 명확하다.

이것을 지적 해준 ghostdog74에게 감사합니다!

os.stat - st_size 크기를 바이트 단위로 제공합니다. 파일 크기 및 기타 파일 관련 정보를 얻는 데 사용될 수도 있습니다.

import os

nbytes = sum(d.stat().st_size for d in os.scandir('.') if d.is_file())

2018 업데이트

Python 3.4 또는 이전 버전을 사용하는 경우 walk타사 scandir패키지 에서 제공 하는보다 효율적인 방법을 사용하는 것이 좋습니다. Python 3.5 이상에서이 패키지는 표준 라이브러리에 통합되었으며os.walk 이에 따라 성능이 향상되었습니다.

2019 업데이트

최근에 pathlib점점 더 많이 사용 하고 있으며 pathlib해결책은 다음과 같습니다.

from pathlib import Path

root_directory = Path('.')
sum(f.stat().st_size for f in root_directory.glob('**/*') if f.is_file())

14
+1이지만 oneliner는 재귀 적이 지 않기 때문에 유효한 결과를 반환하지 않습니다
luc

2
예, 플랫 디렉토리 케이스 전용입니다.
monkut

35
정말 재미있게 한 줄에 재귀 크기를 사용할 수 있습니다.
driax

2
그러나 st_size심볼릭 링크를 따르지 않으려면을 사용해야 lstat합니다.
asmeurer

3
경고! 이것은 'du -sb'와 동일하지 않습니다. Samuel Lampa의 답변을보십시오! 코드는 FAT를 저장하는 데 사용되는 폴더의 크기를 무시합니다.
Yauhen Yakimovich

43

지금까지 제안 된 접근법 중 일부는 재귀를 구현하고 다른 접근법은 쉘을 사용하거나 깔끔한 형식의 결과를 생성하지 않습니다. 코드가 Linux 플랫폼에서 일회성 인 경우 평소처럼 재귀가 포함 된 한 줄짜리 서식을 지정할 수 있습니다. print마지막 줄에서를 제외하고 현재 버전의 python2및에서 작동합니다 python3.

du.py
-----
#!/usr/bin/python3
import subprocess

def du(path):
    """disk usage in human readable format (e.g. '2,1GB')"""
    return subprocess.check_output(['du','-sh', path]).split()[0].decode('utf-8')

if __name__ == "__main__":
    print(du('.'))

간단하고 효율적이며 파일 및 다중 레벨 디렉토리에서 작동합니다.

$ chmod 750 du.py
$ ./du.py
2,9M

13
Nb. 리눅스 전용.
meawoppl

15
본질적으로 크로스 플랫폼 인 파이썬은 아마도 이것으로부터 부끄러워 할 것입니다
Jonathan

11
이 말씀에 감사드립니다. 플랫폼 의존성에 대한 몇 가지 경고를 대답에 추가했습니다. 그러나 일회성 스크립팅 인 경우 많은 Python 코드가 사용됩니다. 이러한 코드는 단지 휴대 성을 위해, 기능 제한, 시간이 오래 걸리고 오류가 발생하기 쉬운 구절, 또는 가장자리의 경우에 드문 결과와 함께 안 어떤 필요 이상 . 항상 그렇듯이 트레이드 오프이며, 현명하게 선택하는 것은 개발자의 책임입니다.)
flaschbier

9
Nitpick : Linux가 아니라 Unix / Posix에만 해당 :)
Mr Shark

3
검색을 파일 시스템으로 제한하려면 du 명령에 '-x'옵션을 추가하는 것이 좋습니다. 즉, [ 'du', '-shx', path]를 대신 사용하십시오.
Keith Hanlan

24

다음은 "du -sb"를 실행할 때와 정확히 동일한 바이트를 반환하는 재귀 함수 (모든 하위 폴더와 해당 파일의 크기를 재귀 적으로 합한 것)입니다. 리눅스에서 ( "."는 "현재 폴더"를 의미합니다) :

import os

def getFolderSize(folder):
    total_size = os.path.getsize(folder)
    for item in os.listdir(folder):
        itempath = os.path.join(folder, item)
        if os.path.isfile(itempath):
            total_size += os.path.getsize(itempath)
        elif os.path.isdir(itempath):
            total_size += getFolderSize(itempath)
    return total_size

print "Size: " + str(getFolderSize("."))

2
이 함수는 심볼릭 링크의 크기도 계산합니다. 심볼릭 링크를 건너 뛰려면 os.path.isfile (itempath) 및 os.path.islink (itempath) 및 elif os.path.isdir ( itempath) 및 os.path.islink (itempath).
airween

17

파이썬 3.5 재귀 폴더 크기 os.scandir

def folder_size(path='.'):
    total = 0
    for entry in os.scandir(path):
        if entry.is_file():
            total += entry.stat().st_size
        elif entry.is_dir():
            total += folder_size(entry.path)
    return total

1
재귀에 대해 걱정하지 않는 경우 Python 3 단일 라이너 방법 sum([entry.stat().st_size for entry in os.scandir(file)]). 참고 출력은 바이트 단위이며 / 1024는 KB를, / (1024 * 1024)는 MB를 나타냅니다.
weiji14

4
@ weiji14 괄호를 잃습니다 (예 :) sum(entry.stat().st_size for entry in os.scandir(file)). sum반복자를 가져 오기 때문에 목록을 만들 이유가 없습니다 .
Vedran Šego

8

monknut 응답은 좋지만 symlink가 끊어지면 실패 하므로이 경로가 실제로 존재하는지 확인해야합니다

if os.path.exists(fp):
    total_size += os.stat(fp).st_size

3
심볼릭 링크를 따르고 싶지 않을 것입니다. 을 사용해야합니다 lstat.
asmeurer

8

허용되는 답변은 하드 링크 또는 소프트 링크를 고려하지 않으며 해당 파일을 두 번 계산합니다. 본 inode를 추적하고 해당 파일의 크기를 추가하지 않으려 고합니다.

import os
def get_size(start_path='.'):
    total_size = 0
    seen = {}
    for dirpath, dirnames, filenames in os.walk(start_path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            try:
                stat = os.stat(fp)
            except OSError:
                continue

            try:
                seen[stat.st_ino]
            except KeyError:
                seen[stat.st_ino] = True
            else:
                continue

            total_size += stat.st_size

    return total_size

print get_size()

5
사용을 고려 os.lstat(이 아니라 os.stat심볼릭 링크 다음)하는 피합니다 : docs.python.org/2/library/os.html#os.lstat
피터 브릭스

7

Chris의 대답은 좋지만 보이는 디렉토리를 확인하기 위해 세트를 사용하여 관용적으로 만들 수 있으며 제어 흐름에 예외를 사용하지 않아도됩니다.

def directory_size(path):
    total_size = 0
    seen = set()

    for dirpath, dirnames, filenames in os.walk(path):
        for f in filenames:
            fp = os.path.join(dirpath, f)

            try:
                stat = os.stat(fp)
            except OSError:
                continue

            if stat.st_ino in seen:
                continue

            seen.add(stat.st_ino)

            total_size += stat.st_size

    return total_size  # size in bytes

2
Chris의 답변은 또한 심볼릭 링크 나 디렉토리 자체의 크기를 고려하지 않습니다. 이에 따라 답변을 편집했습니다. 고정 기능의 출력은 이제 동일합니다 df -sb.
Creshal

7

재귀 원 라이너 :

def getFolderSize(p):
   from functools import partial
   prepend = partial(os.path.join, p)
   return sum([(os.path.getsize(f) if os.path.isfile(f) else getFolderSize(f)) for f in map(prepend, os.listdir(p))])

1
그래도 하나의 라이너가 아닙니다. 그러나 폴더의 폴더 크기가 여러 개인 경우에도 폴더 크기를 바이트 단위로 재귀 적으로 계산하고 올바른 값을 제공합니다.
Venkatesh

나는 이것을 사용하기 쉬운 것으로 가서 Windows에서 처음으로 일했다
hum3

5

질문의 두 번째 부분

def human(size):

    B = "B"
    KB = "KB" 
    MB = "MB"
    GB = "GB"
    TB = "TB"
    UNITS = [B, KB, MB, GB, TB]
    HUMANFMT = "%f %s"
    HUMANRADIX = 1024.

    for u in UNITS[:-1]:
        if size < HUMANRADIX : return HUMANFMT % (size, u)
        size /= HUMANRADIX

    return HUMANFMT % (size,  UNITS[-1])

5

사용 pathlib하여 폴더의 크기를 얻기 위해이 하나의 라이너를 찾았습니다.

sum(file.stat().st_size for file in Path(folder).rglob('*'))

그리고 이것은 좋은 형식의 출력을 위해 생각해 낸 것입니다.

from pathlib import Path


def get_folder_size(folder):
    return ByteSize(sum(file.stat().st_size for file in Path(folder).rglob('*')))


class ByteSize(int):

    _kB = 1024
    _suffixes = 'B', 'kB', 'MB', 'GB', 'PB'

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        self.bytes = self.B = int(self)
        self.kilobytes = self.kB = self / self._kB**1
        self.megabytes = self.MB = self / self._kB**2
        self.gigabytes = self.GB = self / self._kB**3
        self.petabytes = self.PB = self / self._kB**4
        *suffixes, last = self._suffixes
        suffix = next((
            suffix
            for suffix in suffixes
            if 1 < getattr(self, suffix) < self._kB
        ), last)
        self.readable = suffix, getattr(self, suffix)

        super().__init__()

    def __str__(self):
        return self.__format__('.2f')

    def __repr__(self):
        return '{}({})'.format(self.__class__.__name__, super().__repr__())

    def __format__(self, format_spec):
        suffix, val = self.readable
        return '{val:{fmt}} {suf}'.format(val=val, fmt=format_spec, suf=suffix)

    def __sub__(self, other):
        return self.__class__(super().__sub__(other))

    def __add__(self, other):
        return self.__class__(super().__add__(other))

    def __mul__(self, other):
        return self.__class__(super().__mul__(other))

    def __rsub__(self, other):
        return self.__class__(super().__sub__(other))

    def __radd__(self, other):
        return self.__class__(super().__add__(other))

    def __rmul__(self, other):
        return self.__class__(super().__rmul__(other))   

용법:

>>> size = get_folder_size("c:/users/tdavis/downloads")
>>> print(size)
5.81 GB
>>> size.GB
5.810891855508089
>>> size.gigabytes
5.810891855508089
>>> size.PB
0.005674699077644618
>>> size.MB
5950.353260040283
>>> size
ByteSize(6239397620)

나는 또한 파일 크기를 인쇄하기위한 더 작고 성능이 좋은 전략을 가지고있는 이 질문을 보았습니다.


4

다음과 같이 할 수 있습니다 :

import commands   
size = commands.getoutput('du -sh /path/').split()[0]

이 경우 명령을 사용하여 결과를 확인할 수 있도록 반환하기 전에 결과를 테스트하지 않았습니다.


os.walk하위 폴더 크기를 재귀 적으로 확인하는 데 사용하는 성능과 비교하여 성능은 어떻습니까?
TomSawyer


4

파티에 약간 늦었지만 한 줄에 glob2인간화가 설치되어 있다면 . Python 3에서 기본값 iglob은 재귀 모드입니다. Python 3의 코드를 수정하는 방법은 독자에게 간단한 연습으로 남아 있습니다.

>>> import os
>>> from humanize import naturalsize
>>> from glob2 import iglob
>>> naturalsize(sum(os.path.getsize(x) for x in iglob('/var/**'))))
'546.2 MB'

1
Python 3.5부터 내장 glob함수는 재귀 를 지원합니다. 당신은 사용할 수 있습니다 :glob.glob('/var/**', recursive=True)
adzenith

3

다음 스크립트는 지정된 디렉토리에 대한 모든 서브 디렉토리의 디렉토리 크기를 인쇄합니다. 또한 재귀 함수 호출을 캐싱함으로써 (가능한 경우) 이익을 얻으려고 시도합니다. 인수가 생략되면 스크립트는 현재 디렉토리에서 작동합니다. 출력은 가장 큰 것에서 가장 작은 것까지 디렉토리 크기별로 정렬됩니다. 따라서 필요에 맞게 조정할 수 있습니다.

추신 : 인간 친화적 인 형식으로 디렉토리 크기를 표시하기 위해 레시피 578019를 사용했습니다 ( http://code.activestate.com/recipes/578019/ )

from __future__ import print_function
import os
import sys
import operator

def null_decorator(ob):
    return ob

if sys.version_info >= (3,2,0):
    import functools
    my_cache_decorator = functools.lru_cache(maxsize=4096)
else:
    my_cache_decorator = null_decorator

start_dir = os.path.normpath(os.path.abspath(sys.argv[1])) if len(sys.argv) > 1 else '.'

@my_cache_decorator
def get_dir_size(start_path = '.'):
    total_size = 0
    if 'scandir' in dir(os):
        # using fast 'os.scandir' method (new in version 3.5)
        for entry in os.scandir(start_path):
            if entry.is_dir(follow_symlinks = False):
                total_size += get_dir_size(entry.path)
            elif entry.is_file(follow_symlinks = False):
                total_size += entry.stat().st_size
    else:
        # using slow, but compatible 'os.listdir' method
        for entry in os.listdir(start_path):
            full_path = os.path.abspath(os.path.join(start_path, entry))
            if os.path.isdir(full_path):
                total_size += get_dir_size(full_path)
            elif os.path.isfile(full_path):
                total_size += os.path.getsize(full_path)
    return total_size

def get_dir_size_walk(start_path = '.'):
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(start_path):
        for f in filenames:
            fp = os.path.join(dirpath, f)
            total_size += os.path.getsize(fp)
    return total_size

def bytes2human(n, format='%(value).0f%(symbol)s', symbols='customary'):
    """
    (c) http://code.activestate.com/recipes/578019/

    Convert n bytes into a human readable string based on format.
    symbols can be either "customary", "customary_ext", "iec" or "iec_ext",
    see: http://goo.gl/kTQMs

      >>> bytes2human(0)
      '0.0 B'
      >>> bytes2human(0.9)
      '0.0 B'
      >>> bytes2human(1)
      '1.0 B'
      >>> bytes2human(1.9)
      '1.0 B'
      >>> bytes2human(1024)
      '1.0 K'
      >>> bytes2human(1048576)
      '1.0 M'
      >>> bytes2human(1099511627776127398123789121)
      '909.5 Y'

      >>> bytes2human(9856, symbols="customary")
      '9.6 K'
      >>> bytes2human(9856, symbols="customary_ext")
      '9.6 kilo'
      >>> bytes2human(9856, symbols="iec")
      '9.6 Ki'
      >>> bytes2human(9856, symbols="iec_ext")
      '9.6 kibi'

      >>> bytes2human(10000, "%(value).1f %(symbol)s/sec")
      '9.8 K/sec'

      >>> # precision can be adjusted by playing with %f operator
      >>> bytes2human(10000, format="%(value).5f %(symbol)s")
      '9.76562 K'
    """
    SYMBOLS = {
        'customary'     : ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'),
        'customary_ext' : ('byte', 'kilo', 'mega', 'giga', 'tera', 'peta', 'exa',
                           'zetta', 'iotta'),
        'iec'           : ('Bi', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'),
        'iec_ext'       : ('byte', 'kibi', 'mebi', 'gibi', 'tebi', 'pebi', 'exbi',
                           'zebi', 'yobi'),
    }
    n = int(n)
    if n < 0:
        raise ValueError("n < 0")
    symbols = SYMBOLS[symbols]
    prefix = {}
    for i, s in enumerate(symbols[1:]):
        prefix[s] = 1 << (i+1)*10
    for symbol in reversed(symbols[1:]):
        if n >= prefix[symbol]:
            value = float(n) / prefix[symbol]
            return format % locals()
    return format % dict(symbol=symbols[0], value=n)

############################################################
###
###  main ()
###
############################################################
if __name__ == '__main__':
    dir_tree = {}
    ### version, that uses 'slow' [os.walk method]
    #get_size = get_dir_size_walk
    ### this recursive version can benefit from caching the function calls (functools.lru_cache)
    get_size = get_dir_size

    for root, dirs, files in os.walk(start_dir):
        for d in dirs:
            dir_path = os.path.join(root, d)
            if os.path.isdir(dir_path):
                dir_tree[dir_path] = get_size(dir_path)

    for d, size in sorted(dir_tree.items(), key=operator.itemgetter(1), reverse=True):
        print('%s\t%s' %(bytes2human(size, format='%(value).2f%(symbol)s'), d))

    print('-' * 80)
    if sys.version_info >= (3,2,0):
        print(get_dir_size.cache_info())

샘플 출력 :

37.61M  .\subdir_b
2.18M   .\subdir_a
2.17M   .\subdir_a\subdir_a_2
4.41K   .\subdir_a\subdir_a_1
----------------------------------------------------------
CacheInfo(hits=2, misses=4, maxsize=4096, currsize=4)

편집 : 사용자 2233949 권장으로 null_decorator를 위로 옮겼습니다.


스크립트는 잘 작동하지만 'if sys.version_info> = ...'줄 위로 null_decorator 함수를 이동해야합니다. 그렇지 않으면 'null_decorator'가 정의되지 않은 예외를 얻습니다. 그래도 잘 작동합니다.
user2233949

@ user2233949 감사합니다! 해당 코드를 수정했습니다.
MaxU

3

라이브러리 sh 사용 : 모듈 du이 수행하는 작업 :

pip install sh

import sh
print( sh.du("-s", ".") )
91154728        .

별표를 전달하려면 여기에glob 설명 된대로 사용 하십시오 .

사람이 읽을 수있는 값을 변환하려면 humanize를 사용하십시오 .

pip install humanize

import humanize
print( humanize.naturalsize( 91157384 ) )
91.2 MB

2

하나의 파일 크기를 얻기 위해 os.path.getsize ()가 있습니다.

>>> import os
>>> os.path.getsize("/path/file")
35L

바이트 단위로보고됩니다.


2

가치가있는 것을 위해 ... 트리 명령은이 모든 것을 무료로 수행합니다.

tree -h --du /path/to/dir  # files and dirs
tree -h -d --du /path/to/dir  # dirs only

나는 파이썬을 좋아하지만 문제에 대한 가장 간단한 해결책은 새로운 코드가 필요하지 않습니다.


@ Abdur-RahmaanJanhangeer, 이것은 사실입니다. 사실입니다.
meh

2

편리합니다 :

import os
import stat

size = 0
path_ = ""
def calculate(path=os.environ["SYSTEMROOT"]):
    global size, path_
    size = 0
    path_ = path

    for x, y, z in os.walk(path):
        for i in z:
            size += os.path.getsize(x + os.sep + i)

def cevir(x):
    global path_
    print(path_, x, "Byte")
    print(path_, x/1024, "Kilobyte")
    print(path_, x/1048576, "Megabyte")
    print(path_, x/1073741824, "Gigabyte")

calculate("C:\Users\Jundullah\Desktop")
cevir(size)

Output:
C:\Users\Jundullah\Desktop 87874712211 Byte
C:\Users\Jundullah\Desktop 85815148.64355469 Kilobyte
C:\Users\Jundullah\Desktop 83803.85609722137 Megabyte
C:\Users\Jundullah\Desktop 81.83970321994275 Gigabyte

1

나는 scandir 과 함께 python 2.7.13을 사용 하고 있으며 폴더의 전체 크기를 가져 오는 한 줄짜리 재귀 함수가 있습니다.

from scandir import scandir
def getTotFldrSize(path):
    return sum([s.stat(follow_symlinks=False).st_size for s in scandir(path) if s.is_file(follow_symlinks=False)]) + \
    + sum([getTotFldrSize(s.path) for s in scandir(path) if s.is_dir(follow_symlinks=False)])

>>> print getTotFldrSize('.')
1203245680

https://pypi.python.org/pypi/scandir


1

하위 디렉토리의 크기를 계산할 때 상위 폴더의 폴더 크기를 업데이트해야하며 이는 루트 상위에 도달 할 때까지 계속됩니다.

다음 함수는 폴더와 모든 하위 폴더의 크기를 계산합니다.

import os

def folder_size(path):
    parent = {}  # path to parent path mapper
    folder_size = {}  # storing the size of directories
    folder = os.path.realpath(path)

    for root, _, filenames in os.walk(folder):
        if root == folder:
            parent[root] = -1  # the root folder will not have any parent
            folder_size[root] = 0.0  # intializing the size to 0

        elif root not in parent:
            immediate_parent_path = os.path.dirname(root)  # extract the immediate parent of the subdirectory
            parent[root] = immediate_parent_path  # store the parent of the subdirectory
            folder_size[root] = 0.0  # initialize the size to 0

        total_size = 0
        for filename in filenames:
            filepath = os.path.join(root, filename)
            total_size += os.stat(filepath).st_size  # computing the size of the files under the directory
        folder_size[root] = total_size  # store the updated size

        temp_path = root  # for subdirectories, we need to update the size of the parent till the root parent
        while parent[temp_path] != -1:
            folder_size[parent[temp_path]] += total_size
            temp_path = parent[temp_path]

    return folder_size[folder]/1000000.0

1

Windows OS를 사용하는 경우 다음을 수행 할 수 있습니다.

다음을 실행하여 pywin32 모듈을 설치하십시오.

pip install pywin32

그런 다음 다음을 코딩하십시오.

import win32com.client as com

def get_folder_size(path):
   try:
       fso = com.Dispatch("Scripting.FileSystemObject")
       folder = fso.GetFolder(path)
       size = str(round(folder.Size / 1048576))
       print("Size: " + size + " MB")
   except Exception as e:
       print("Error --> " + str(e))

1

다음은 재귀 적으로 수행하는 하나의 라이너입니다 (Python 3.5에서 사용 가능한 재귀 옵션).

import os
import glob
print(sum(os.path.getsize(f) for f in glob.glob('**', recursive=True) if os.path.isfile(f))/(1024*1024))

1

파이썬 3.5 이상

from pathlib import Path

def get_size(path):
    return sum(p.stat().st_size for p in Path(path).rglob('*'))

0

이 스크립트는 CWD에서 가장 큰 파일을 알려주고 파일이 어떤 폴더에 있는지 알려줍니다. 이 스크립트는 win8 및 python 3.3.3 쉘에서 작동합니다.

import os

folder=os.cwd()

number=0
string=""

for root, dirs, files in os.walk(folder):
    for file in files:
        pathname=os.path.join(root,file)
##        print (pathname)
##        print (os.path.getsize(pathname)/1024/1024)
        if number < os.path.getsize(pathname):
            number = os.path.getsize(pathname)
            string=pathname


##        print ()


print (string)
print ()
print (number)
print ("Number in bytes")

0

분명히 이것은 일종의 해킹이며 유닉스 / 리눅스에서만 작동합니다.

du -sb .사실상 이것은 du -sb .명령 을 실행하는 Python bash 래퍼이기 때문에 일치 합니다 .

import subprocess

def system_command(cmd):
    """"Function executes cmd parameter as a bash command."""
    p = subprocess.Popen(cmd,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         shell=True)
    stdout, stderr = p.communicate()
    return stdout, stderr

size = int(system_command('du -sb . ')[0].split()[0])

0

나는 조금 늦었고 (새로운) Linux에서 하위 프로세스 모듈과 'du'명령 줄을 사용하여 폴더 크기에 대한 정확한 값을 MB 단위로 검색하도록 선택했습니다. 그렇지 않으면 하위 프로세스에서 0이 아닌 값이 반환되어 오류가 발생하기 때문에 루트 폴더에 if 및 elif를 사용해야했습니다.

import subprocess
import os

#
# get folder size
#
def get_size(self, path):
    if os.path.exists(path) and path != '/':
        cmd = str(subprocess.check_output(['sudo', 'du', '-s', path])).\
            replace('b\'', '').replace('\'', '').split('\\t')[0]
        return float(cmd) / 1000000
    elif os.path.exists(path) and path == '/':
        cmd = str(subprocess.getoutput(['sudo du -s /'])). \
            replace('b\'', '').replace('\'', '').split('\n')
        val = cmd[len(cmd) - 1].replace('/', '').replace(' ', '')
        return float(val) / 1000000
    else: raise ValueError

0

디렉토리 크기 가져 오기

솔루션의 속성 :

  • 겉보기 크기 (파일의 바이트 수)와 파일이 사용하는 실제 디스크 공간을 모두 반환합니다.
  • 하드 링크 된 파일을 한 번만 계산
  • 같은 방식으로 심볼릭 링크를 계산 du 수행
  • 재귀를 사용하지 않습니다
  • 사용 st.st_blocks된 디스크 공간에 사용되므로 유닉스 계열 시스템에서만 작동

코드:

import os


def du(path):
    if os.path.islink(path):
        return (os.lstat(path).st_size, 0)
    if os.path.isfile(path):
        st = os.lstat(path)
        return (st.st_size, st.st_blocks * 512)
    apparent_total_bytes = 0
    total_bytes = 0
    have = []
    for dirpath, dirnames, filenames in os.walk(path):
        apparent_total_bytes += os.lstat(dirpath).st_size
        total_bytes += os.lstat(dirpath).st_blocks * 512
        for f in filenames:
            fp = os.path.join(dirpath, f)
            if os.path.islink(fp):
                apparent_total_bytes += os.lstat(fp).st_size
                continue
            st = os.lstat(fp)
            if st.st_ino in have:
                continue  # skip hardlinks which were already counted
            have.append(st.st_ino)
            apparent_total_bytes += st.st_size
            total_bytes += st.st_blocks * 512
        for d in dirnames:
            dp = os.path.join(dirpath, d)
            if os.path.islink(dp):
                apparent_total_bytes += os.lstat(dp).st_size
    return (apparent_total_bytes, total_bytes)

사용법 예 :

>>> du('/lib')
(236425839, 244363264)

$ du -sb /lib
236425839   /lib
$ du -sB1 /lib
244363264   /lib

사람이 읽을 수있는 파일 크기

솔루션의 속성 :

코드:

def humanized_size(num, suffix='B', si=False):
    if si:
        units = ['','K','M','G','T','P','E','Z']
        last_unit = 'Y'
        div = 1000.0
    else:
        units = ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']
        last_unit = 'Yi'
        div = 1024.0
    for unit in units:
        if abs(num) < div:
            return "%3.1f%s%s" % (num, unit, suffix)
        num /= div
    return "%.1f%s%s" % (num, last_unit, suffix)

사용법 예 :

>>> humanized_size(236425839)
'225.5MiB'
>>> humanized_size(236425839, si=True)
'236.4MB'
>>> humanized_size(236425839, si=True, suffix='')
'236.4M'

0

pathlib를 사용하여 Python 3.6에서 작동하는 솔루션입니다.

from pathlib import Path

sum([f.stat().st_size for f in Path("path").glob("**/*")])

0

사용하여 Python 3.6 이상 재귀 폴더 / 파일 크기 os.scandir. @blakev 의 답변 만큼 강력 하지만 더 짧고 EAFP python 스타일 입니다.

import os

def size(path, *, follow_symlinks=False):
    try:
        with os.scandir(path) as it:
            return sum(size(entry, follow_symlinks=follow_symlinks) for entry in it)
    except NotADirectoryError:
        return os.stat(path, follow_symlinks=follow_symlinks).st_size

0
def recursive_dir_size(path):
    size = 0

    for x in os.listdir(path):
        if not os.path.isdir(os.path.join(path,x)):
            size += os.stat(os.path.join(path,x)).st_size
        else:
            size += recursive_dir_size(os.path.join(path,x))

    return size

나는 디렉토리의 정확한 전체 크기를 제공하는이 기능을 썼다. 나는 os.walk로 다른 for 루프 솔루션을 시도했지만 최종 결과가 항상 실제 크기보다 작은 이유를 모른다 (우분투 18 env). 나는 뭔가 잘못했을 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.