I'm fetching a list with all files/folders on a ftp-server,
I want to put a [F] before a folder, and leave files like they are,
but I can't find a way to check if it's a file or a dir...

I already tried:

from ftplib import FTP
import os
ftp = FTP(self.host)
listdir = self.ftp.nlst()
for i in listdir:
    if(self.ftp.sendcmd(os.path.isdir(bool(self.ftpdir + "/" + i)))):
          self.list_box_2.Append("[F] " + i)

But this ends in an error:

Traceback (most recent call last):
File "./DCM/dcm", line 714, in ftp_start
self.start_ftp()
File "./DCM/dcm", line 671, in start_ftp
self.ftp_show_dir()
File "./DCM/dcm", line 678, in ftp_show_dir
if(self.ftp.sendcmd(os.path.isdir(str(self.ftpdir + "/" + i)))):
File "/usr/lib/python2.6/", line 242, in sendcmd
self.putcmd(cmd)
File "/usr/lib/python2.6/", line 177, in putcmd
self.putline(line)
File "/usr/lib/python2.6/", line 170, in putline
line = line + CRLF
TypeError: unsupported operand type(s) for +: 'bool' and 'str'

Dani AI

Generated

nlst() only returns names; it does not include type info. Relying on os.path.isdir() checks your local filesystem, not the FTP server, which is why that approach fails. The most reliable way to distinguish files from directories across servers is to use the MLST/MLSD extensions (RFC 3659). They return machine-readable facts like type=file or type=dir. Many servers support them, and you can call them even if your Python version lacks FTP.mlsd().

Example using MLST with a graceful fallback to LIST parsing:

def ftp_isdir(ftp, name):
    # Prefer MLST if the server advertises it
    try:
        if 'MLST' in ftp.sendcmd('FEAT'):
            resp = ftp.sendcmd('MLST ' + name)  # e.g. "250- type=dir;... name"
            facts = [p.strip().lower() for p in resp.split() if ';' in p]
            for part in ';'.join(facts).split(';'):
                if part.startswith('type='):
                    return part[5:] == 'dir'
    except Exception:
        pass
    # Fallback: LIST one entry and heuristically parse UNIX format
    lines = []
    try:
        ftp.retrlines('LIST ' + name, lines.append)
        return bool(lines) and lines[0].startswith('d')
    except Exception:
        return False

Note: LIST parsing is not standardized and may be inaccurate on non-UNIX listings. The common "try CWD" trick can misclassify on permission errors or symlinks, so use it only as a last resort. See Python ftplib docs and RFC 3659 MLST/MLSD details in RFC 3659.

Recommended Answers

All 3 Replies

I'm fetching a list with all files/folders on a ftp-server,
I want to put a [F] before a folder, and leave files like they are,
but I can't find a way to check if it's a file or a dir...

I already tried:

from ftplib import FTP
import os
ftp = FTP(self.host)
listdir = self.ftp.nlst()
for i in listdir:
    if(self.ftp.sendcmd(os.path.isdir(bool(self.ftpdir + "/" + i)))):
          self.list_box_2.Append("[F] " + i)

But this ends in an error:

Of course.
You have to use ftp.dir instead of ftp.nlst, and massage the returned list (it will have the information you need and a lot more).

No...
Every FTP server has an other configuration, so it would be very messy to create a script to get what I want from the ftp.dir command
ftp.nlst works fine and gives me a list with all the files/dirs.
but I need something that when I give a name ftp will return what it is: folder or file.

Is this possible with the ftp.dir command if I have the filename?

(It would be handy if it was just for me, but it's a program I'm writing for a lot of people with different ftp servers.)

This is my solution. It isn't pretty...but it works!

def isdir(ftp, name):
   try:
      ftp.cwd(name)
      ftp.cwd('..')
      return True
   except:
      return False
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.