解决python fs(filesystem)库在连接FTP服务器时无法显示文件目录的问题

本文由Markdown语法编辑器编辑完成.

1. 问题提出:

目前有一个需求是:医院的影像数据是存储在FTP服务器上的,医院提供了连接该FTP服务器的host, user, password等参数.(注:该ftp服务是部署在windows操作系统的IIR服务上)

采用的python库是fs(filesystem2)的第三方库.fs==2.0.23版本.

在根据提供的参数,可以正常的连接到该ftp服务器,但是在显示该ftp服务器下的文件目录时,却显示为空.但是,该ftp服务器下的确是有文件夹的.

之前在连接别的医院的ftp服务器时,是可以正常显示ftp服务器下的文件目录的.

通过跟踪代码,发现是由于fs库的内部的一个函数实现,在解析服务器返回的字符串时,返回为空,而导致后续无法检索到文件夹.

定位到的函数是:fs.ftpfs下的_ftp_parse()函数.

IIR服务器返回的lines是:

[
  ‘01-20-19 04:23AM < DIR > 104794_CT‘,
  ‘01-20-19 04:22AM < DIR > 104794_SR‘,
   ‘01-19-19 07:45AM < DIR > 104795_CT‘,
   ‘01-19-19 07:43AM < DIR > 104795_SR‘,
   ‘01-15-19 07:49AM < DIR > 104796_CT‘,
   ‘01-14-19 07:47AM < DIR > 104796_SR‘,
   ‘01-13-19 08:44AM < DIR > 104797_CT‘
 ]

在运行:

python _list = [Info(raw_info) for raw_info in ftp_parse.parse(lines)]

后,_list为[], 因此后续无法检索到图像.

2. 问题分析:

要想解决这个问题,需要对比之前可以正常显示ftp服务器下的文件目录和这里的区别.

通过debug代码发现,当ftp服务是部署在linux服务器时,程序运行到上面的位置时,lines的值的格式为:

[
  u‘drwxr-xr-x    2 ftp      ftp         69632 Jan 30 03:51 3177498‘,
  u‘drwxr-xr-x    2 ftp      ftp         73728 Jan 30 03:51 3177512‘,
  u‘drwxr-xr-x    2 ftp      ftp         77824 Jan 30 03:52 3177517‘,
  u‘drwxr-xr-x    2 ftp      ftp         73728 Jan 30 03:52 3177529‘
]

而fs中解析这个lines的代码为_ftp_parse.py:

re_linux = re.compile(
    """
    ^
    ([ldrwx-]{10})
    \s+?
    (\d+)
    \s+?
    ([\w\-]+)
    \s+?
    ([\w\-]+)
    \s+?
    (\d+)
    \s+?
    (\w{3}\s+\d{1,2}\s+[\w:]+)
    \s+
    (.*?)
    $
    """,
    re.VERBOSE
)

def get_decoders():
    decoders = [
        (re_linux, decode_linux)
    ]
    return decoders

def parse(lines):
    info = []
    for line in lines:
        if not line.strip():
            continue
        raw_info = parse_line(line)
        if raw_info is not None:
            info.append(raw_info)
    return info

def parse_line(line):
    for line_re, decode_callable in get_decoders():
        match = line_re.match(line)
        if match is not None:
            return decode_callable(line, match)
    return None

def decode_linux(line, match):
    perms, links, uid, gid, size, mtime, name = match.groups()
    is_link = perms.startswith(‘l‘)
    is_dir = perms.startswith(‘d‘) or is_link
    if is_link:
        name, _, _link_name = name.partition(‘->‘)
        name = name.strip()
        _link_name = _link_name.strip()
    permissions = Permissions.parse(perms[1:])

    mtime_epoch = _parse_time(mtime)

    name = unicodedata.normalize(‘NFC‘, name)

    raw_info = {
        "basic": {
            "name": name,
            "is_dir": is_dir
        },
        "details": {
            "size": int(size),
            "type": int(
                ResourceType.directory
                if is_dir else
                ResourceType.file
            )
        },
        "access": {
            "permissions": permissions.dump()
        },
        "ftp": {
            "ls": line
        }
    }
    access = raw_info[‘access‘]
    details = raw_info[‘details‘]
    if mtime_epoch is not None:
        details[‘modified‘] = mtime_epoch

    access[‘user‘] = uid
    access[‘group‘] = gid

    return raw_info

从fs的源码中可以看出,_ftp_parse.py中的get_decoders()函数中,decoders这个变量数组中,只提供了一组解码器,即内部的 (re_linux, decode_linux). 因此,当ftp服务器不是部署在linux操作系统上,而是部署在windows等其他操作系统上时,ftp返回的字符串格式,就不再符合解码器中的正则表达式.

因此,要修改这个问题,就需要根据当前IIR服务器返回的字符串的格式,撰写相应的正则表达式来解码,然后加入到_ftp_parse.py中的decoders数组中.

要解决这个问题,就需要对python中的正则表达式有一定的了解.相关的教程可以阅读:正则表达式.

https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386832260566c26442c671fa489ebc6fe85badda25cd000

3. 解决方案:

在了解了正则表达式的规范后,模拟re_linux和decode_linux的函数,可以增加re_windows和decode_windows这两个函数.增加后的函数如下:

re_windows = re.compile(
    """
    ^
    ([\w-]{8}\s+[\w:]+)
    \s+?
    (<DIR>)
    \s+?
    (.*?)
    $
    """,
    re.VERBOSE
)

def decode_windows(line, match):
    mtime, dir, name = match.groups()
    name = name.strip()
    raw_info = {
        "basic": {
            "name": name,
            "is_dir": True
        },
        "ftp": {
            "ls": line
        }
    }
    return raw_info

def get_decoders():
    decoders = [
        (re_linux, decode_linux),
        #这个解码组合是新增的,针对windows操作系统的解码器.
        (re_windows, decode_windows)
    ]
    return decoders

当然,这里的正则表达式是根据之前返回的字符串来撰写的.如果返回的字符串和文章中开头的字符串样式不同,还需要另外修改正则表达式.

原文地址:https://www.cnblogs.com/stephen2014/p/10373930.html

时间: 2024-09-30 04:37:20

解决python fs(filesystem)库在连接FTP服务器时无法显示文件目录的问题的相关文章

FileZilla连接ftp服务器失败,提示&quot;AUTH TLS&quot;解决方法

FileZilla连接ftp服务器失败,提示"AUTH TLS"解决方法 前几天还是能正常连接ftp服务器的,突然一下连接失败,提示"AUTH TLS",用浏览器试了一下"ftp:ip地址",输入用户名.密码后可以正常访问.所以应该是FileZilla软件连接配置有点问题,百度了一下就解决了.记录下解决过程,方便自己查看. 1.连接的提示 连接时并没有提示用户名.密码错误,说明是正确的:查了下,原因是服务器不支持FTP over TLS的连接方式

System.Net.FtpClient库连接ftp服务器

如果自己单枪匹马写一个连接ftp服务器代码那是相当恐怖的(socket通信),有一个评价较高的dll库可以供我们使用. 那就是System.Net.FtpClient,链接地址:https://netftp.codeplex.com 然后下载该资源,我们就可以使用它的函数了.这里介绍一下如何使用System.Net.FtpClient链接ftp服务器并下载服务器中的文件. 千万别忘了添加引用——导入System.Net.FtpClient.dll. 还有就是 using System.Net.F

Mac 使用smb协议连接FTP服务器

在Mac中,可以通过smb协议作为客户端连接到服务器,例如一个FTP服务器,然后获取上面的共享文件. 方法: 1.在Finder菜单中点击前往 -- 连接服务器. 也可以Command + K,也可以右击Finder然后点击连接服务器. 2.输入服务器地址并连接: 3.接下来以客户或注册用户身份登录,后面的就不多说了. Mac 使用smb协议连接FTP服务器,布布扣,bubuko.com

linux下常用FTP命令 1. 连接ftp服务器

1. 连接ftp服务器 格式:ftp [hostname| ip-address]a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码,分别输入用户名和相应密码,待认证通过即可. 2. 下载文件 下载文件通常用get和mget这两条命令.a) get 格式:get [remote-file] [local-file]将文件从远端主机中传送至本地主机中.如要获取远程服务器上/usr/your/1.htm,则 ftp> get /usr/your/1.htm 

linux下常用FTP命令 1. 连接ftp服务器[转]

1. 连接ftp服务器 格式:ftp [hostname| ip-address]a)在linux命令行下输入: ftp 192.168.1.1 b)服务器询问你用户名和密码,分别输入用户名和相应密码,待认证通过即可. 2. 下载文件 下载文件通常用get和mget这两条命令.a) get 格式:get [remote-file] [local-file]将文件从远端主机中传送至本地主机中.如要获取远程服务器上/usr/your/1.htm,则 ftp> get /usr/your/1.htm 

Mac下ssh连接远程服务器时自动断开问题

在mac下使用securecrt通过ssh连接远程服务器时,总会一段时间没有动作后,ssh被自动断开.在windows下用xmanager貌似没有遇到过这个问题. 在网上找了解决方法如下: 客户端配置: Global.ini文件中将D:"Disconnect After Resume Timeout"=00000000改为D:"Disconnect After Resume Timeout"=FFFFFFFF securecrt界面上配置:send string \

局域网内计算机访问FTP服务器时,提示“无法访问服务器名称或地址

局域网内计算机访问FTP服务器时,提示“无法访问服务器名称或地址”,一般由三个原因造成:一.防火墙未关闭解决方法如下:1.单击屏幕左下角的”开始“菜单2.在弹出菜单中单击”控制面板“3.点击”系统和安全“4.点击”Winsows 防火墙“5.单击左侧的”打开或关闭Windows防火墙“6.在”家庭或工作网络位置设置“和”公用网络位置设置“两项里选择关闭防火墙,单击”确定“即可.二.设置有误,FTP被动模式没有禁止.解决方法如下:1.打开浏览器,点击”工具“2.在下拉菜单中点击”Internet选

Win7 自带FTP将文件复制到FTP服务器时发生错误。

错误截图: 错误信息: 将文件复制到FTP服务器时发生错误.请检查是否有权限将文件放到该服务器上. 详细信息: 200 Type set to I. 200 PORT commad successful. 451 No mapping for the Unicode character exits in target multi-bye code page. 解决方案: 控制面板-->管理工具-->打开Internet信息服务(IIS)管理器.右键选中自己建立好的FTP站点,选择"管

命令行连接mysql服务器时 报Can&#39;t connect to local MySQL server through socket &#39;xxx.sock&#39;错误

本来之前用的好好的mysql服务器,突然就报Can't connect to local MySQL server through socket 'xxx.sock'错误了 遇到该问题思路首先是:检查 my.cnf 中 socket 配置的路径及权限. 但是查看完 没发现路劲权限有问题,最后跑去另一台同时配置的服务器上看  发现/data/perconadata有一个/mnt/perconadata/mysql.sock的软连接 于是乎到问题机器上 cd /data/perconadata/ s