5

While the following code works well in windows, in Linux server (of pythonanywhere) the function only returns 0, without errors. What am I missing?

import os

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

print(folder_size("/media"))

Ref: Code from https://stackoverflow.com/a/37367965/6546440

Community
  • 1
  • 1
Rashomon
  • 5,962
  • 4
  • 29
  • 67
  • 3
    Does `/media` contain any files? Usually it only contains a few empty directories (until you plug in a CDROM or a memory stick). – Antonis Christofides Nov 28 '16 at 08:49
  • Please refer http://stackoverflow.com/questions/1392413/calculating-a-directory-size-using-python#1392549 also. – Sanket Sudake Nov 28 '16 at 08:50
  • @AntonisChristofides Yes, it has files... – Rashomon Nov 28 '16 at 08:53
  • 1
    PythonAnywhere dev here -- `/media/` is an empty directory in all accounts on our site, and it's not writable. Are you trying to work out the size of a directory containing uploaded media -- say, from a Django site? That would be something more like `/home/yourusername/yoursitename/media`. – Giles Thomas Nov 29 '16 at 13:46
  • Yes, later I saw that was the problem...thanks! – Rashomon Nov 29 '16 at 14:57

5 Answers5

2

The solution was given by @gilen-tomas in the comments:

import os

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

print(folder_size("/home/your-user/your-proyect/media/"))

A complete path is needed!

Rashomon
  • 5,962
  • 4
  • 29
  • 67
1

It's worked for me in linux (Ubuntu server 16.04, python 3.5), but there could be some permission errors if the process doesn't have permission for reading a file.

Kenly
  • 24,317
  • 7
  • 44
  • 60
  • As I say in the description, theres no error... Maybe you are right and I dont have permission in the server. I will investigate this – Rashomon Nov 28 '16 at 08:52
  • I tested it again. It works. Return 0 in case of the folder is empty. – Dávid Fazekas Nov 28 '16 at 09:09
  • I've removed the question from your answer since that seems to be attracting flags (where as the permissions may be the actual problem here). When you get 50 reputation you'll be able to leave comments to allow you to ask for further information – Sayse Nov 28 '16 at 09:22
1

Depending on the filesystem, the underlying struct dirent may not know if any given entry is a file or directory (or something else). Perhaps, on the filesystem used by pythonanywhere, you need to stat first (stat_result.st_type ought to be valid).

Edit: A look in discussion on os.scandir suggests the DT_UNKNOWN case is handled by doing another stat. I'd still try confirming those checks work as expected.

Yann Vernier
  • 15,414
  • 2
  • 28
  • 26
1

you can try this..

For linux :

import os
path = '/home/user/Downloads'
folder = sum([sum(map(lambda fname: os.path.getsize(os.path.join(directory, fname)), files)) for directory, folders, files in os.walk(path)])
MB=1024*1024.0
print  "%.2f MB"%(folder/MB)

For windows :

import win32com.client as com
folderPath = r"/home/user/Downloads"
fso = com.Dispatch("Scripting.FileSystemObject")
folder = fso.GetFolder(folderPath)
MB=1024*1024.0
print  "%.2f MB"%(folder.Size/MB)
Shivkumar kondi
  • 6,458
  • 9
  • 31
  • 58
  • Syntax error... what about `print (sum(map(lambda fname: os.path.getsize(os.path.join(directory, fname)), files)) for directory, folders, files in os.walk(path))`? I get ` at 0x7fe197d2edb0>`... – Rashomon Nov 28 '16 at 09:35
  • I got a syntax error in `print "%.2f MB"%(folder/MB)`. Anyway, `folder` returns 0 :( – Rashomon Nov 28 '16 at 09:42
  • There is no error if I call `print(folder)`. The terminal prints `0`. – Rashomon Nov 28 '16 at 09:45
  • @flashter so you are using pythonV3 . just enclose the print () statement. and try to check other folders too. and please accept (check tick)to the answer if it satisfies your need. – Shivkumar kondi Nov 28 '16 at 09:48
0

Not a solution for this, but other way to get the size is using the cmd from python:

import subprocess
import re

cmd = ["du", "-sh", "-b", "media"]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
tmp = str(proc.stdout.read())
tmp = re.findall('\d+', tmp)[0]

print(tmp)

If you are executing this from your proyect (instead of manually in the terminal) a complete path is needed in "media" ("/home/your-user/your-proyect/media/")

Rashomon
  • 5,962
  • 4
  • 29
  • 67