17

リモート ftp 上のファイルがフォルダーであるか、ftplib を使用していないかを確認するにはどうすればよいですか?

私が今持っている最善の方法は、nlstを実行し、各ファイルでサイズを呼び出すことを繰り返すことです.ファイルがエラーになった場合、それはフォルダですか?

より良い方法はありますか?約 12 の異なる ftp サーバー (多くは非常に古いもの) があるため、list の出力を解析できません。

私は何をすべきか?

4

15 に答える 15

9

ftplib には「isdir」と「isfile」の定義はありません。ftplibを使用する必要がない場合は、ftputilを使用することをお勧めします。

まず、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")
于 2016-10-11T15:01:01.133 に答える
7

FTP は非常に初歩的なプロトコルであり、各ノードのタイプ (ファイル、ディレクトリ) を取得できる組み込みのプロトコル クエリがないため、見つけたようなヒューリスティックが唯一の解決策です。

各ノードのサイズを取得できない場合は、それらのノードのそれぞれで呼び出すことを検討する必要FTP.nlst()があります。エラーが発生するのはディレクトリではなくファイルです。

于 2009-12-31T14:28:08.573 に答える
4

FTP.dirディレクトリのリストを返します。これをコールバック関数で解析して、ディレクトリであるかどうかを確認できます。たとえば、次のようにします。

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

ftp.dir(parse)
于 2009-07-06T17:55:52.707 に答える
4
def is_file(filename):
    return ftp.size(filename) is not None

ディレクトリの場合、ftp.size は None を返すため、これは機能します。

于 2009-07-06T18:01:04.833 に答える
4

MLST コマンドを使用できます。

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

pyftpdlibサーバーに対して、上記のコードは以下を出力します。

250-Listing "/":
 modify=20111212124834;perm=el;size=12288;type=dir;unique=807g100001; /
250 End MLST.

あなたがしなければならないことは、その文字列を解析し、「type = dir」または「type = cdir」(「。」のような現在のディレクトリ)または「type = pdir」(「..」のような親ディレクトリ)を探すことです。正規表現。一致した場合は、指定されたパスがディレクトリを参照していることを意味します。

于 2011-12-12T12:51:09.967 に答える
1

これは、特定のディレクトリ内のディレクトリを見つけるために使用するものです。プログラムの後半でセットを使用するため、ディレクトリ名をセットとして返しますが、最後にセットの作成を省略して、ディレクトリ名をリスト、タプルなどとして返すこともできます。

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
于 2013-05-24T07:24:38.700 に答える
1
def is_file(filename):
    current = ftp.pwd()
    try:
        ftp.cwd(filename)
    except:
        ftp.cwd(current)
        return True
    ftp.cwd(current)
    return False

ここに別の解決策があります。書き途中で、問題があることに気づきました。フォルダに変更する権限がない場合は、代わりにファイルとして読み込まれます。任意のフォルダにアクセスできる場合に機能します。

多分それはいくつかのアイデアを与えるかもしれないので、私はまだそれを投稿しました.

于 2009-07-06T18:49:41.723 に答える
1

私は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!"
于 2012-05-18T19:52:42.410 に答える
0

解決策を見つけましたが、最善ではない可能性があり、お役に立てると思います。

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

この関数は、「remote_name」が通常のファイルの場合に TRUE を返し、それ以外の場合は False を返します。

于 2014-12-05T17:29:33.477 に答える
0

この関数は、 がファイルのTrue場合は を返し、そうでない場合は を返します。objectFalse

def _is_file(FTP, object):
    if FTP.nlst(object) == [object]:
        return True
    else:
        return False

使用例:

import ftplib

with ftplib.FTP(host=ftp_link, user=ftp_username, passwd=ftp_password) as FTP:
    if _is_file(FTP, object='/path/filename.extention'):
        print(object, 'is file!')
    else:
        print(object, 'is directory!')

FTP.nlst()はどのように機能しますか?

  1. FTP.nlst(object)[object]がファイルの場合に返しobjectます。
  2. FTP.nlst(object)objectが空のフォルダの場合、空のリストを返します。
  3. FTP.nlst(object)objectがファイルまたはディレクトリを含むフォルダである場合、文字列のリストを返します。
于 2019-08-15T04:04:15.257 に答える
-3

すべてのファイルには拡張子があるため、split('.') を使用すると、サイズ 2 のリストに分割できます。一方、ディレクトリの場合、split('.') を使用した後のリストのサイズは 1 になります。したがって、リストのサイズを確認することで、ファイルかディレクトリかを識別できます。

os.chdir(r"path")
ftp = ftplib.FTP('ftp.some.server')
ftp.login('username','password')
filelist=ftp.nlst()
for file in filelist:
    fildir=file.split('.')
    filsize=len(fildir)
    if(filsize>1):
        ftp.retrbinary('RETR %s' %file, open(file, 'wb').write)
ftp.close()
于 2015-01-25T20:37:04.373 に答える