2009-07-06 145 views
12

如何檢查遠程ftp上的文件是否是使用ftplib的文件夾?ftplib檢查文件是否是文件夾?

我現在最好的方法是做一個nlst,並通過調用每個文件的大小迭代,如果文件錯誤,那麼它是一個文件夾?

有沒有更好的方法?我無法解析列表的輸出,因爲有大約十幾個不同的ftp服務器(很多很老)。

我該怎麼辦?

回答

4

FTP.dir返回目錄列表,你可以用一個回調函數解析,找出它是否是一個目錄。例如,像這樣:

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

ftp.dir(parse) 
+1

但產量不標準,所以它沒用。 – UberJumper 2009-07-06 18:16:21

+0

好吧,然後用不同的函數解析它。肯定沒有那麼多類型的迴應。 – SilentGhost 2009-07-06 18:19:41

+1

現在考慮一下,有57個不同的遠程ftp服務器,一些運行linux/windows/HPUX/solaris/BSD ftp客戶端,+第三方ftp客戶端的隨機過多。它是一種痛苦。 – UberJumper 2009-07-06 18:28:33

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

這工作,因爲ftp.size返回None,如果它是一個目錄。

+0

問題是我只注意到其中一個ftp服務器,實際上是返回一個文件夾的文件大小。這不應該發生,但它確實如此。喬利。 – UberJumper 2009-07-06 18:13:28

+0

在py3k – SilentGhost 2009-07-06 18:18:58

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

這是另一種解決方案。一半寫出來,我意識到它有一個問題。如果您沒有權限更改爲文件夾,則會將其作爲文件讀取。如果你有權訪問任何文件夾,它將工作。

我仍然發佈它,因爲它可能會提供一些想法。

6

FTP是一個相當基本的協議,並沒有內置協議的查詢,讓您獲得的類型每個節點(文件,目錄),所以像你找到了一個啓發是唯一的解決辦法。

如果獲取每個節點的大小不起作用,或許您應該考慮在每個節點上調用FTP.nlst():那些出錯將是文件而不是dirs。

3

可以使用MLST命令:

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

反對pyftpdlib server上面打印的代碼:

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

,你所要做的是分析該字符串並查找 「類型= DIR」 或「鍵入= cdir「(當前目錄,如」。「)或」type = pdir「(父目錄,如」..「)通過正則表達式。 如果您得到一個匹配,這意味着提供的路徑指的是一個目錄。

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!" 
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 
0

我返回目錄名已找到解決方案,但它可能不是最好的,我認爲它可能對您有所幫助。

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

如果'remote_name'是普通文件,則此函數將返回TRUE,否則將返回False。

-3

所有文件的擴展,因此通過採用分體式(「‘),它可以被分成大小2列表雖然目錄列表的大小將是一個採用分體式後(’。」)。所以通過檢查列表的大小,我們可以確定它是一個文件還是一個目錄。

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() 
4

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

我的整個解決方案是這樣的:

def is_file(filename): 
    try: 
     ftp.cwd(filename) 
    except Exception as e: 
     if "550" in e: 
      return True 
    return False 
0
ftp_conn = FTP(host=host_name, user=user_name, passwd=password, acct='', timeout=None, source_address=None) 
ftp_conn.cwd(path_ftp) 
for data_dir in ftp_conn.mlsd(): 
    print(data_dir) 

輸出:

('3', {'modify': '20170719134928', 'perm': 'flcdmpe', 'type': 'dir', 'unique': '804U485826E', 'unix.group': '10000', 'unix.mode': '0755', 'unix.owner': '10754'}) 

see 'type': 'dir' 
0
def _get_file_type(self, path): 
    """ 
Returns string parsed from MLST command 
    """ 
    try: 
     return_str = self.ftp.sendcmd('MLST ' + path) 
    except BaseException as e: 
     raise BaseException("No such file or directory") 
    c = re.search('Type=(dir|file);', return_str) 
    try: 
     filetype = c.group(1) 
    except AttributeError as e: 
     raise BaseException("Unable to parse") 
    return filetype 


def is_file(self,path): 
    """ 
Returns if a filepath is a file 
    """ 
    filetype = self._get_file_type(path) 
    if filetype == 'file': 
     return True 
    return False 
相關問題