python ftplib 检查文件是否是文件夹?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1088336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:27:05  来源:igfitidea点击:

ftplib checking if a file is a folder?

pythonftpftplib

提问by UberJumper

How can i check if a file on a remote ftp is a folder or not using ftplib?

如何使用 ftplib 检查远程 ftp 上的文件是否是文件夹?

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?

我现在最好的方法是做一个 nlst,并迭代调用每个文件的大小,如果文件出错,那么它是一个文件夹?

Is there a better way? I cannot parse the output of list, since there is about a dozen different ftp servers(many extremely old.)

有没有更好的办法?我无法解析列表的输出,因为大约有十几个不同的 ftp 服务器(许多非常老旧。)

What should i do?

我该怎么办?

回答by Antoine P.

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.

FTP 是一个相当基本的协议,没有内置的协议查询允许您获取每个节点的类型(文件、目录),因此像您发现的那样的启发式方法是唯一的解决方案。

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.

如果获取每个节点的大小不起作用,也许您应该考虑调用FTP.nlst()每个节点:那些出错的将是文件而不是目录。

回答by Ceylan B.

There are not "isdir" and "isfile" definitions in ftplib. If you don't have to use ftplib, i recommend you to use ftputil.

ftplib 中没有“isdir”和“isfile”定义。如果您不必使用 ftplib,我建议您使用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:

首先,您必须安装 ftputil 包。为了实现这一目标,使用这个命令:python -m pip install ftputil。安装后,您可以将库导入到您的代码中。我觉得解释就够了。那么,让我们进入实现:

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")

回答by SilentGhost

FTP.dirreturns a directory listing, that you can parse with a callback function to find out whether it's a directory. For example, like this:

FTP.dir返回一个目录列表,您可以使用回调函数对其进行解析,以确定它是否是一个目录。例如,像这样:

def parse(line):
    if line[0] == 'd':
        print(line.rpartition(' ')[2])   # gives you the name of a directory

ftp.dir(parse)

回答by Giampaolo Rodolà

You can use MLST command:

您可以使用 MLST 命令:

import ftplib
f = ftplib.FTP()
f.connect("localhost")
f.login()
print f.sendcmd('MLST /')

Against pyftpdlib serverthe code above prints:

针对pyftpdlib 服务器,上面的代码打印:

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.

您需要做的是解析该字符串并通过以下方式查找“type=dir”或“type=cdir”(当前目录,如“.”)或“type=pdir”(父目录,如“..”)一个正则表达式。如果匹配,则表示提供的路径是指目录。

回答by Evan Fosmark

def is_file(filename):
    return ftp.size(filename) is not None

This works because ftp.size returns None if it is a directory.

这是有效的,因为 ftp.size 返回 None 如果它是一个目录。

回答by Evan Fosmark

def is_file(filename):
    current = ftp.pwd()
    try:
        ftp.cwd(filename)
    except:
        ftp.cwd(current)
        return True
    ftp.cwd(current)
    return False

Here is another solution. Half way writing it out I realized it has a problem. If you don't have permission to change to a folder, it'll read it as a file instead. It'll work if you have access to any folder.

这是另一种解决方案。写到一半才发现有问题。如果您无权更改文件夹,它会将其作为文件读取。如果您有权访问任何文件夹,它将起作用。

I still posted it because maybe it'll give some ideas.

我仍然发布它,因为它可能会提供一些想法。

回答by jameh

I have used this when dealing with ftplib:

我在处理 ftplib 时使用过这个:

import ftplib
from ftplib import FTP
ftp=FTP("ftp address")
ftp.login("user","password")

path = "/is/this/a/file/or/a/folder/"

try:
    ftp.cwd(path)
    print "it's a folder!"
except ftplib.error_perm:
    print "it's not a folder!"

回答by Daniel Lee

This is what I use for finding the directories in a given directory. I return the directory names as a set because I use sets later on in the program, but you could leave off the set creation at the end and return the directory names as a list, tuple, etc.

这是我用于在给定目录中查找目录的方法。我将目录名称作为集合返回,因为我稍后会在程序中使用集合,但是您可以在最后不创建集合,并将目录名称作为列表、元组等返回。

def get_directories(ftp_server):
    """
    Returns a set of directories in the current directory on the FTP server

    Stdout output of ftp_server.dir() is redirected to an IO object and then
    reset, because ftp_server.dir() only prints its results to stdout.

    @param ftp_server: Open connection to FTP server
    @return: Set of directory names
    """
    # Redirect stdout
    old_stdout = sys.stdout
    sys.stdout = new_stdout = StringIO()
    # Get directory listing
    ftp_server.dir()
    # Reset stdout
    sys.stdout = old_stdout

    directory_listing = new_stdout.getvalue().split("\n")
    # Directories are listed starting with "d" for "directory"
    only_directories = (x for x in directory_listing if x.startswith("d"))
    # This only deals with directory names without spaces.
    directory_names = set(dirname.split()[-1] for dirname in only_directories)
    return directory_names

回答by Diego Vélez

I have found a solution, but it may not be the best and I think it can be helpful for you.

我找到了一个解决方案,但它可能不是最好的,我认为它可能对您有所帮助。

> def isfile(remote_name):
>     try:
>         ftp.sendcmd('MDTM ' + remote_name)
>     except:
>         return False
>     else:
>         return True

This function will return TRUE if 'remote_name' is a regular file, otherwise will return False.

如果“remote_name”是常规文件,则此函数将返回 TRUE,否则将返回 False。

回答by Nick

My entire solution looks like this:

我的整个解决方案如下所示:

def is_file(filename):
    try:
        ftp.cwd(filename)
    except Exception as e:
        if "550" in e:
            return True
    return False