পাইথন ব্যবহার করে কোনও ডিরেক্টরি আকারের গণনা করছেন?


181

আমি এই বিশেষ চাকাটি পুনরায় উদ্ভাবন করার আগে পাইথন ব্যবহার করে কোনও ডিরেক্টরি আকারের গণনা করার জন্য কি কেউ একটি দুর্দান্ত রুটিন পেয়েছে? এটি খুব সুন্দর হবে যদি রুটিনটি এমবি / জিবি ইত্যাদিতে আকারটি সুন্দরভাবে ফর্ম্যাট করে would


13
এটি খুব সুন্দর হবে না। আকারটি গণনা করার জন্য আপনার একটি ফাংশন থাকতে হবে এবং একটি স্বতন্ত্র ফাংশন (এটি মেমরির আকারগুলির সাথেও ব্যবহৃত হতে পারে) উদাহরণস্বরূপ "আকারটি এমবি / জিবি ইত্যাদিতে সুন্দরভাবে ফর্ম্যাট করতে"।
জন মাচিন

17
হ্যাঁ আমি জানি তবে এটি দুটি প্রশ্ন জিজ্ঞাসা করে সংরক্ষণ করে।
গ্যারি উইলফোবি

1
tree* স্নো সিস্টেমে কমান্ড বিনামূল্যে জন্য এই সব করে। tree -h -d --du /path/to/dir
meh

@ মীহdu -sh /path/to/dir/*
মৃগলুম

উত্তর:


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 ( উপ-ডিরেক্টরি অন্তর্ভুক্ত করে না ) ব্যবহার করে মজার জন্য একটি অনেলাইনার :

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

রেফারেন্স:

আপডেট করা হয়েছে os.path.getsize ব্যবহার করার জন্য , এটি os.stat ()। St_size পদ্ধতি ব্যবহার করার চেয়ে পরিষ্কার।

এটিকে নির্দেশ করার জন্য ঘোস্টডোগ 74 কে ধন্যবাদ!

os.stat - st_size বাইট আকারে দেয়। ফাইল আকার এবং অন্যান্য ফাইল সম্পর্কিত তথ্য পেতে ব্যবহার করা যেতে পারে।

import os

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

আপডেট 2018

আপনি যদি পাইথন ৩.৪ বা তার আগের ব্যবহার করেন তবে আপনি walkতৃতীয় পক্ষের scandirপ্যাকেজ দ্বারা সরবরাহিত আরও কার্যকর পদ্ধতি ব্যবহারের বিষয়ে বিবেচনা করতে পারেন । পাইথন 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
আসল মজাদার জন্য আপনি এক লাইনে একটি পুনরাবৃত্ত আকার করতে পারেন: যোগফল (d.path.getsize (os.path.join (dirpath, ফাইলের নাম)) dirpath জন্য, dirnames, os.walk এ ফাইলের নাম (PATH) ফাইলের মধ্যে ফাইলের নাম জন্য)
ড্রিक्स

2
তবে আপনাকে ব্যবহার করতে হবে st_sizeযদি আপনি সিমলিংকগুলি অনুসরণ না করতে চান তবে আপনার ব্যবহার করা উচিত lstat
asmeurer

3
সতর্কবাণী! এটি 'ডু-এসবি' এর মতো নয়। স্যামুয়েল লম্পার উত্তর দেখুন! আপনার কোডটি FAT সঞ্চয় করতে ব্যবহৃত ফোল্ডারের আকারটিকে উপেক্ষা করে।
ইয়াহেন ইয়াকিমোভিচ

43

এখন পর্যন্ত প্রস্তাবিত কয়েকটি পদ্ধতির কোনও পুনরাবৃত্তি বাস্তবায়ন করার জন্য, অন্যরা শেল নিয়োগ করে বা ঝরঝরে ফর্ম্যাটিত ফলাফল দেয় না। আপনার কোডটি লিনাক্স প্ল্যাটফর্মগুলির জন্য এক-অফ থাকলে, আপনি যথারীতি ফর্ম্যাটিং পেতে পারেন, পুনরাবৃত্তি অন্তর্ভুক্ত, ওয়ান-লাইনার হিসাবে। 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
নম্বর। শুধুমাত্র লিনাক্স।
meawoppl

15
পাইথন প্রকৃতির ক্রস প্ল্যাটফর্ম হওয়ায় সম্ভবত এ থেকে লজ্জা পাওয়া উচিত
জোনাথন

11
এই মন্তব্যগুলির জন্য ধন্যবাদ। আমি উত্তরে প্ল্যাটফর্ম নির্ভরতা সম্পর্কিত কিছু সাবধানতা যুক্ত করেছি। তবে পাইথন কোড অনেকটাই যদি এক-অফ স্ক্রিপ্টিং হয়। এই জাতীয় কোডটি কেবল কোনও প্রয়োজনের বাইরে বহনযোগ্যতার স্বার্থে কার্যকরী সীমাবদ্ধতা, দীর্ঘতর এবং ত্রুটি-প্রবণ প্যাসেজগুলি বা প্রান্ত ক্ষেত্রে অস্বাভাবিক ফলাফলের সাথে আসা উচিত নয় । এটি, বরাবরের মতো, একটি বাণিজ্য বন্ধ, এবং বুদ্ধিমানের সাথে চয়ন করা বিকাশকারীর দায়িত্ব;)
ফ্ল্যাশবিয়ার

9
নিতপিক: লিনাক্স নয় তবে ইউনিক্স / পিক্সিক নির্দিষ্ট :)
মিঃ শার্ক

3
ফাইল-সিস্টেমে অনুসন্ধান সীমাবদ্ধ করার জন্য ডু কমান্ডে '-x' বিকল্পটি যুক্ত করা বুদ্ধিমানের কাজ। অন্য কথায় এর পরিবর্তে ['du', '-shx', পাথ] ব্যবহার করুন।
কিথ হ্যানলান

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 (পুনরায়) এবং os.path.islink (পুনরায়) এবং এলিফ os.path.isdir ( পুনরুদ্ধার) এবং os.path.islink (পুনরায়) mp
এয়ার

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
পুনরাবৃত্ত-নেস সম্পর্কে উদ্বিগ্ন না হলে পাইথন 3 ওয়ান-লাইনার পদ্ধতি sum([entry.stat().st_size for entry in os.scandir(file)])। নোট আউটপুট বাইটে রয়েছে, / 1024 কেবি পেতে এবং / (1024 * 1024) এমবি পেতে।
weiji14

4
@ weiji14 বন্ধনীগুলি হারাবেন, অর্থাত্‍ sum(entry.stat().st_size for entry in os.scandir(file)),। তালিকা তৈরি করার কোনও কারণ নেই, কারণ sumপুনরাবৃত্তির পাশাপাশি নেওয়া হয়।
বেদরান Šego

8

সন্ন্যাসীর উত্তর ভাল তবে এটি ভাঙা সিমলিংকে ব্যর্থ হয়, সুতরাং আপনাকেও এই পরীক্ষাটি দেখতে হবে যে এই পথটি আসলেই আছে কিনা

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

3
আপনি সম্ভবত প্রতিলিঙ্কগুলি অনুসরণ করতে চান না। আপনার ব্যবহার করা উচিত lstat
asmeurer

8

গৃহীত উত্তরটি শক্ত বা নরম লিঙ্কগুলিতে বিবেচনা করে না এবং এই ফাইলগুলিকে দু'বার গণনা করবে। আপনি কোন ইনোড দেখেছেন সেগুলি ট্র্যাক করে রাখতে চান এবং সেই ফাইলগুলির জন্য আকার যুক্ত করবেন না।

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) ব্যবহারের কথা বিবেচনা করুন , যা নিম্নলিখিত প্রতীকী লিঙ্কগুলিকে এড়িয়ে চলে: ডকস.পিথথন.আর
পিটার ব্রিগেস

7

ক্রিসের উত্তরটি ভাল তবে দেখা ডিরেক্টরিগুলি পরীক্ষা করার জন্য একটি সেট ব্যবহার করে আরও মূর্তিমানিক তৈরি করা যেতে পারে যা নিয়ন্ত্রণ প্রবাহের ক্ষেত্রেও ব্যতিক্রম ব্যবহার এড়িয়ে যায়:

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
ক্রিসের উত্তরগুলি সিমলিংকগুলি বা ডিরেক্টরিগুলির আকারগুলি নিজেরাই গ্রহণ করে না। আমি আপনার উত্তরটি সেই অনুযায়ী সম্পাদনা করেছি, স্থির ফাংশনের আউটপুট এখন একইরকম df -sb
ক্রিশাল

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
এটি যদিও এক লাইনার নয়। যাইহোক, এটি পুনরাবৃত্তভাবে ফোল্ডারের আকার গণনা করে (এমনকি ফোল্ডারের ভিতরে একাধিক ফোল্ডার থাকলেও) বাইটে এবং সঠিক মান দেয়।
ভেঙ্কটেশ

আমি এটি ব্যবহারে সহজ হিসাবে চলে গিয়েছিলাম এবং উইন্ডোজে প্রথমবার কাজ করেছি
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]

এই ক্ষেত্রে আমি ফলাফলটি ফেরত দেওয়ার আগে পরীক্ষা করে দেখিনি, আপনি যদি চান তবে আপনি এটি কমান্ডের মাধ্যমে পরীক্ষা করতে পারেন can


os.walkপুনরাবৃত্তভাবে সাব ফোল্ডার আকার পরীক্ষা করতে ব্যবহারের তুলনায় পারফরম্যান্স কেমন ?
টমসওয়ায়ার

4

আপনি যে ওয়ান লাইনার বলেছেন ... এখানে একটি ওয়ান লাইনার:

sum([sum(map(lambda fname: os.path.getsize(os.path.join(directory, fname)), files)) for directory, folders, files in os.walk(path)])

যদিও আমি সম্ভবত এটি বিভক্ত করব এবং এটি কোনও পরীক্ষা করে না।

কেবিতে রূপান্তর করতে পুনরায় ব্যবহারযোগ্য লাইব্রেরিটি ফাইলের আকারের মানব পাঠযোগ্য সংস্করণ পেতে দেখুন? এবং এটি কাজ


4

একটু পার্টি দেরী কিন্তু এক লাইন দেওয়া থাকা ব্যক্তিগণ glob2 এবং সুরুচিকর ইনস্টল করা নেই। দ্রষ্টব্য যে পাইথন 3 এ, ডিফল্টটিতে iglobএকটি পুনরাবৃত্ত মোড থাকে। পাইথন 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
পাইথন ৩.৫ দিয়ে শুরু করে বিল্ট-ইন globপুনরাবৃত্তি সমর্থন করে। আপনি ব্যবহার করতে পারেন:glob.glob('/var/**', recursive=True)
অ্যাডজিনিথ

3

নিম্নলিখিত ডিরেক্টরিতে সমস্ত সাব ডিরেক্টরি ডিরেক্টরি নিম্নলিখিত স্ক্রিপ্ট ডিরেক্টরি আকার মুদ্রণ। এটি পুনরাবৃত্ত ফাংশনের কলগুলি ক্যাশে করে (সম্ভব হলে) উপকারের চেষ্টা করে। যদি কোনও যুক্তি বাদ দেওয়া হয় তবে স্ক্রিপ্টটি বর্তমান ডিরেক্টরিতে কাজ করবে। আউটপুট ডিরেক্টরি আকার থেকে বৃহত্তম থেকে ক্ষুদ্রতম পর্যন্ত বাছাই করা হয়। সুতরাং আপনি এটি আপনার প্রয়োজনের জন্য খাপ খাইয়ে নিতে পারেন।

PS আমি মানব-বান্ধব বিন্যাসে ডিরেক্টরি আকার দেখানোর জন্য 578019 রেসিপি ব্যবহার করেছি ( http://code.activestate.com/recips/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)

সম্পাদনা: উপরের নাল_ডেকোরেটর সরানো হয়েছে, ব্যবহারকারীর 23233949 হিসাবে প্রস্তাবিত


আপনার স্ক্রিপ্টটি ভালভাবে কাজ করে, তবে আপনাকে 'if sys.version_info> = ...' লাইনের উপরে নাল_ডিকোরেটর ফাংশনটি সরানো দরকার। অন্যথায় আপনি একটি 'নাল_ডেকোরেটর' পাবেন ব্যতিক্রম সংজ্ঞায়িত নয়। যদিও এর পরে দুর্দান্ত কাজ করে।
user2233949

@ ইউজার ২৩৩৯৯৯৯, আপনাকে ধন্যবাদ! আমি কোড অনুসারে সংশোধন করেছি।
ম্যাকসু

3

লাইব্রেরি sh ব্যবহার করুন : মডিউলটি duএটি করে:

pip install sh

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

আপনি যদি অস্ট্রিক্স পাস করতে চান তবে এখানেglob বর্ণিত হিসাবে ব্যবহার করুন

মানুষের readables মান রূপান্তর করতে, ব্যবহার সুরুচিকর :

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

আমি পাইথনকে ভালবাসি তবে সমস্যাটির সহজ সমাধানের জন্য কোনও নতুন কোডের প্রয়োজন নেই।


@ আবদুর-রাহমান জানহানগীর, এটি সত্য। এটা সত্য.
মেহ

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

আমি পাইথন 2.7.13 ব্যবহার করছি সঙ্গে scandir এবং এখানে আমার এক-লাইনের রিকার্সিভ ফাংশন একটি ফোল্ডার মোট আকার পেতে আছে:

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

আপনি যদি উইন্ডোজ ওএসে থাকেন তবে আপনি এটি করতে পারেন:

চালু করে মডিউল পাইওয়ুইন 32 ইনস্টল করুন:

পাইপ ইনস্টল 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

এখানে একটি লাইনার যা এটি পুনরাবৃত্তি করে (পাইথন 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))


0

এই স্ক্রিপ্টটি আপনাকে জানায় যে কোন ফাইলটি সিডাব্লুডির মধ্যে সবচেয়ে বড় এবং ফাইলটি কোন ফোল্ডারে রয়েছে তাও আপনাকে জানায়। এই স্ক্রিপ্টটি win8 এবং পাইথন 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 .কমান্ডটি চালায় ।

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

আমি এখানে একটু দেরি করেছি (এবং নতুন) তবে আমি এমবিতে ফোল্ডারের আকারের জন্য একটি সঠিক মান পুনরুদ্ধার করতে লিনাক্সের সাথে সাবপ্রসেসি মডিউল এবং 'ডু' কমান্ড লাইনটি ব্যবহার করতে পছন্দ করেছি। রুট ফোল্ডারের জন্য যদি আমাকে এবং এলিফ ব্যবহার করতে হয় কারণ অন্যথায় সাব-প্রসেস শূন্য-না হওয়া মানের কারণে ত্রুটি উত্থাপন করে।

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

ডিরেক্টরি আকার পান

সমাধানের বৈশিষ্ট্যগুলি:

  • উভয়ই প্রত্যাবর্তন করে: আপাত আকার (ফাইলের বাইট সংখ্যা) এবং ফাইলগুলি ব্যবহার করে প্রকৃত ডিস্ক স্পেস।
  • হার্ড লিঙ্কযুক্ত ফাইলগুলি একবারই গণনা করে
  • একইভাবে symlinks গণনা করা হয় 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

মানব পাঠযোগ্য ফাইল আকার size

সমাধানের বৈশিষ্ট্যগুলি:

কোড:

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

পাইথন 3.6+ পুনরাবৃত্ত ফোল্ডার / ফাইল আকার ব্যবহার করে os.scandir। হিসেবে শক্তিশালী উত্তর @blakev দ্বারা, কিন্তু ছোট এবং EAFP পাইথন শৈলী

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

আমি এই ফাংশনটি লিখেছি যা আমাকে একটি ডিরেক্টরিের সঠিক সামগ্রিক আকার দেয়, আমি ওএসওয়াকের সাথে লুপ সমাধানের জন্য অন্য চেষ্টা করেছিলাম তবে কেন জানি না যে শেষ ফলাফলটি সবসময় আসল আকারের চেয়ে কম ছিল (উবুন্টু 18 এনভিতে)। আমি অবশ্যই কিছু ভুল করে ফেলেছি তবে কে জানে এটি এই লিখেছেন পুরোপুরি ভাল কাজ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.