3

I'm using FtpLib (Python) to download a folder with files from an ftp server. But I want to know the size of the folder before I start downloading it.

In the documentation I found FTP.size(filename) but that's just for files and not for folders... I could loop through all the files in the folder but it is possible that the folder contains subfolders.

So does anyone know how to get the size of the folder using FtpLib?

Bach
  • 6,145
  • 7
  • 36
  • 61
Frederik Voordeckers
  • 1,321
  • 15
  • 31
  • I dont know if there is a ready to use python lib/module but ftp's structure doesn't allow this. It seems that u must sum file sizes under a folder within your code and u must do this recursively to get the folder size. – obayhan Feb 28 '14 at 08:56

3 Answers3

8

After some trial and error I found the solution.

It's based on Alex Thorntons solution but I kept in mind that there could be subfolders. When it's a folder, the ftp.cwd() command succeeds and the function is called recursively.

When the ftp.cwd() command throws an error, it was a file and we can get the file size. The type is set to "I" (images), this forces binary mode since the ftp.size() command is not allowed in ASCII mode.

def get_total_size(self, directory):
    size = 0
    for filename in self.ftp.nlst(directory):
        try:
            self.ftp.cwd(filename)
            size += self.get_total_size(filename)
        except:
            self.ftp.voidcmd('TYPE I')
            size += self.ftp.size(filename)
    return size
Frederik Voordeckers
  • 1,321
  • 15
  • 31
2
def get_size(directory):
    size = 0
    for file in FTP.nlst(directory):
        size += FTP.size(file)
    return size
anon582847382
  • 19,907
  • 5
  • 54
  • 57
2

Frederik Voordeckers' solution didn't work for me. When the method is called recursively, when dealing with a structure of subfolders, it raises the error 550 directory/.../sub_directory: No such file or directory.
I did modify his original code, by deleting the "self-declarations", since I did not use the method inside a class. This might have caused the error. I don't know.

Here is my solution:

def get_total_size(ftp_dir):
    size = 0
    parent_dir = ftp.pwd() # get the current directory
    for filename in ftp.nlst(ftp_dir):
        # (don't forget to import os)
        path = os.path.join(parent_dir, filename) # keeps recursively track of the path
        try:
            ftp.cwd(path)
            size += get_total_size(path)
            ftp.cwd(parent_dir)
        except:
            ftp.voidcmd('TYPE I')
            size += ftp.size(path)
    return size

Should work like a charm for everyone.

St4rb0y
  • 317
  • 3
  • 5
  • 22