0

I'm trying to print the name and the size of all files in a directory and all its sub-directories, but it only prints the name and size of the files in the first directory but not the sub-directories. Any help will be appreciated.

import os
path = os.getcwd()
walk_method = os.walk(path)
while True:
    try:
        p, sub_dir, files = next(walk_method)
        break
    except:
        break
size_of_file = [
    (f, os.stat(os.path.join(path, f)).st_size)
    for f in files
]
for sub in sub_dir:
    i = os.path.join(path, sub)
    size = 0
    for k in os.listdir(i):
        size += os.stat(os.path.join(i, k)).st_size
    size_of_file.append((sub, size))
for f, s in sorted(size_of_file, key = lambda x: x[1]):
    print("{} : {}MB".format(os.path.join(path, f), round(s/(1024*1024), 3)))

I'm expecting to print the name and file size of all files in the current directory and all the sub-directories.

Tim
  • 1
  • 2
  • You'll need to recursively walk through all the `sub_dirs`; I might suggest making a `set` of `sub_dirs` and adding to that set every time you find a directory, and popping from that set to walk through it; keep walking/adding/popping until the set is empty. (Might need to also check against an `already_visited` set to make sure you don't get stuck in a symlink-loop.) – Joshua Voskamp Jan 12 '23 at 19:50
  • Does this answer your question? [Getting a list of all subdirectories in the current directory](https://stackoverflow.com/questions/973473/getting-a-list-of-all-subdirectories-in-the-current-directory) – Joshua Voskamp Jan 12 '23 at 19:52

2 Answers2

0

The documentation has some helpful example code that you might have chosen to follow. A loop forever / next() / break approach could be made to work, I'm sure, but it's not idiomatic and that style does not improve the maintainability of the code.

from pathlib import Path
import os

total = 0
for root, dirs, files in os.walk("."):
    for file in files:
        path = Path(root) / file
        print(path)
        total += path.stat().st_size

print(f"Total of {total} bytes.")
J_H
  • 17,926
  • 4
  • 24
  • 44
0

pathlib is amazing here I think, there are many ways of solving this but one simple example is something like this:

from pathlib import Path

dir = "."
paths = list(Path(dir).glob('**/*'))
for path in paths:
    if path.is_file():
        print(f"{path.name}, {path.lstat().st_size}")

You don't need the loop but for simplicity in this example I just used it.