ftplib checking if a file is a folder?
Solution 1
There are not "isdir" and "isfile" definitions in ftplib. If you don't have to use ftplib, i recommend you to use ftputil.
First of all you have to install ftputil package. To achive this, use this command: python -m pip install ftputil
. After the installation, you can import the library to your code. I think it's enough explanation. So, let's go to the implementation:
import ftputil
with ftputil.FTPHost("host", "username", "password") as ftp_host:
ftp_host.chdir("/directory/")
list = ftp_host.listdir(ftp_host.curdir)
for fname in list:
if ftp_host.path.isdir(fname):
print(fname + " is a directory")
else:
print(fname + " is not a directory")
Solution 2
FTP is quite a rudimentary protocol and there's no built-in protocol query allowing you to get the type (file, dir) of each node, so a heuristic like the one you found is the only solution.
If getting the size of each node doesn't work, perhaps you should consider calling FTP.nlst()
on each of those nodes: those that error out will be files rather than dirs.
Solution 3
FTP.dir
returns a directory listing, that you can parse with a callback function to find out whether it's a directory. For example, like this:
def parse(line):
if line[0] == 'd':
print(line.rpartition(' ')[2]) # gives you the name of a directory
ftp.dir(parse)
Solution 4
def is_file(filename):
return ftp.size(filename) is not None
This works because ftp.size returns None if it is a directory.
Solution 5
You can use MLST command:
import ftplib
f = ftplib.FTP()
f.connect("localhost")
f.login()
print f.sendcmd('MLST /')
Against pyftpdlib server the code above prints:
250-Listing "/":
modify=20111212124834;perm=el;size=12288;type=dir;unique=807g100001; /
250 End MLST.
What you have to do is parse that string and look for "type=dir" or "type=cdir" (current dir, as in ".") or "type=pdir" (parent dir as in "..") via a regular expression. If you get a match, it means that the provided path refers to a directory.
Related videos on Youtube
tenstormavi
Updated on April 17, 2022Comments
-
tenstormavi about 2 years
How can i check if a file on a remote ftp is a folder or not using ftplib?
Best way i have right now is to do a nlst, and iterate through calling size on each of the files, if the file errors out then it is a folder?
Is there a better way? I cannot parse the output of list, since there is about a dozen different ftp servers(many extremely old.)
What should i do?
-
tenstormavi almost 15 yearsThe problem is i just noticed that one of the ftp servers, actually returns the filesize of a folder. Which shouldnt happen, but it does. Jolly.
-
tenstormavi almost 15 yearsBut the output is not standard, so its useless.
-
SilentGhost almost 15 yearswell, parse it with a different function then. surely there isn't as many types of responses.
-
Evan Fosmark almost 15 years@uberjumper, I have one more idea to try that I'll post soon. That's really surprising that it returns the folder size. @SilentGhost, I did it in 2.6, but thanks for the note. If I share it with someone using 3.x I'll be sure to give them a modified version.
-
tenstormavi almost 15 yearsWell considering right now at count there is 57 different remote ftp servers, some running linux/windows/HPUX/solaris/BSD ftp clients, + the random plethora of 3rd party ftp clients. Its a pain.
-
tenstormavi almost 15 yearsYes i know, also it returns the MDTM date also. I've seen one or two other ftp servers that dump folder sizes, but don't dump file modification dates. I eagrly await your solution.
-
SilentGhost almost 15 yearswhy do you think that there will be as many response formats? as long as some form of drwxrwxrwx is there, you can split string and use regexp or other technique to find out what field contains permission.
-
jameh almost 12 yearslike @Evan Fosmark said, if user does not have suff. permissions to cwd a given folder, this code will identify that folder as a file.
-
pajaja over 9 yearsPresumption that all files have extension is wrong.
-
hasufell almost 8 yearsThanks, this is the correct answer. rfc3659 specifies the exact format of the response, so this can be reliably machine-parsed.
-
Nick about 7 yearsI solved the issue by checking if the error it throws contains "550 Access is Denied". This works for the server to which I am connected, but I am doubtful that all servers will respond in this fashion. Perhaps a dictionary of known 550 error messages can be used? Or just check if it says "550"?
-
dgundersen about 6 yearsMight be because of the server but when I tried this nlst() doesn't error on files. When called on a file it returned a list of length 1 containing the filename so I was able to look at that to determine if it was a file or dir.