如何檢查遠程ftp上的文件是否是使用ftplib的文件夾?ftplib檢查文件是否是文件夾?
我現在最好的方法是做一個nlst,並通過調用每個文件的大小迭代,如果文件錯誤,那麼它是一個文件夾?
有沒有更好的方法?我無法解析列表的輸出,因爲有大約十幾個不同的ftp服務器(很多很老)。
我該怎麼辦?
如何檢查遠程ftp上的文件是否是使用ftplib的文件夾?ftplib檢查文件是否是文件夾?
我現在最好的方法是做一個nlst,並通過調用每個文件的大小迭代,如果文件錯誤,那麼它是一個文件夾?
有沒有更好的方法?我無法解析列表的輸出,因爲有大約十幾個不同的ftp服務器(很多很老)。
我該怎麼辦?
FTP.dir
返回目錄列表,你可以用一個回調函數解析,找出它是否是一個目錄。例如,像這樣:
def parse(line):
if line[0] == 'd':
print(line.rpartition(' ')[2]) # gives you the name of a directory
ftp.dir(parse)
def is_file(filename):
return ftp.size(filename) is not None
這工作,因爲ftp.size返回None,如果它是一個目錄。
問題是我只注意到其中一個ftp服務器,實際上是返回一個文件夾的文件大小。這不應該發生,但它確實如此。喬利。 – UberJumper 2009-07-06 18:13:28
在py3k – SilentGhost 2009-07-06 18:18:58
def is_file(filename):
current = ftp.pwd()
try:
ftp.cwd(filename)
except:
ftp.cwd(current)
return True
ftp.cwd(current)
return False
這是另一種解決方案。一半寫出來,我意識到它有一個問題。如果您沒有權限更改爲文件夾,則會將其作爲文件讀取。如果你有權訪問任何文件夾,它將工作。
我仍然發佈它,因爲它可能會提供一些想法。
FTP是一個相當基本的協議,並沒有內置協議的查詢,讓您獲得的類型每個節點(文件,目錄),所以像你找到了一個啓發是唯一的解決辦法。
如果獲取每個節點的大小不起作用,或許您應該考慮在每個節點上調用FTP.nlst()
:那些出錯將是文件而不是dirs。
可以使用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「(父目錄,如」..「)通過正則表達式。 如果您得到一個匹配,這意味着提供的路徑指的是一個目錄。
與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!"
這是我使用在指定目錄查找的目錄。我返回目錄名稱爲一組,因爲我在以後的程序上使用集,但你可以在最後離開落定的創建和作爲一個列表,元組等
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
我返回目錄名已找到解決方案,但它可能不是最好的,我認爲它可能對您有所幫助。
> def isfile(remote_name):
> try:
> ftp.sendcmd('MDTM ' + remote_name)
> except:
> return False
> else:
> return True
如果'remote_name'是普通文件,則此函數將返回TRUE,否則將返回False。
所有文件的擴展,因此通過採用分體式(「‘),它可以被分成大小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()
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")
我的整個解決方案是這樣的:
def is_file(filename):
try:
ftp.cwd(filename)
except Exception as e:
if "550" in e:
return True
return False
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'
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
但產量不標準,所以它沒用。 – UberJumper 2009-07-06 18:16:21
好吧,然後用不同的函數解析它。肯定沒有那麼多類型的迴應。 – SilentGhost 2009-07-06 18:19:41
現在考慮一下,有57個不同的遠程ftp服務器,一些運行linux/windows/HPUX/solaris/BSD ftp客戶端,+第三方ftp客戶端的隨機過多。它是一種痛苦。 – UberJumper 2009-07-06 18:28:33