从 python ftplib 中使用 FTP_TLS 时从 retrlines() 获取 EOFError

问题描述 投票:0回答:1

这对我来说没有任何意义。为我可怜的 python 道歉,我对这门语言还比较陌生。

我的程序的相关部分如下所示:

from ftplib import FTP, FTP_TLS

...

        try:
            ftps = FTP(server, user = user, passwd = password,
            encoding='ISO8859-1'
            )
            # ftps.prot_p()
            login = True
        except:
            print("Login failed, retry")
...
        for member in members:

            ftps.retrlines(f'RETR {member}', lines.append)

            fp = open(f'{dest}/{type}/{member}{sep}{suffix}', 'w',
                    encoding='ISO8859-1', errors='backslashreplace')
            line_number = 0
            for line in lines:
                line_number += 1
                bad = [line_number, line]
                line = line.replace('\xdd', '|')

                try:
                    fp.write(line.rstrip() + '\n')
                except:
                    print(f"line {bad[0]} in {type} member:",
                          f"{member}{sep}{suffix} - {bad[1]}")
            fp.close()
...

效果很好,并且已经使用了几年了。但是,当我将其更改为:

            ftps = FTP_TLS(server, user = user, passwd = password,
            encoding='ISO8859-1'
            )
            ftps.prot_p()
            login = True

我得到: 文件“~\Local\Programs\Python\Python311\Lib tplib.py”,第 218 行,在 getline 中 引发 EOF 错误 EOF错误

我尝试将 ftps.retrlines() 包装在 try/ except 子句中以忽略 EOFError (来自另一个 SO 线程的建议),但这导致了更多 ssl 错误。

我查看了服务器上的文件以及下载后的文件(至少与发生错误的位置一致),并且在源文件中没有看到任何导致此问题的内容。查看“错误”文件之前和之后的(服务器)文件,如果我不使用 FTP_TLS,两者看起来都很好并且下载没有问题。

完全公开,该服务器是启用了 FTPS 的 z/OS 服务器,这些是 z/OS 上的 PDS 的成员。

蒂亚

python ftplib ftps
1个回答
0
投票

更新:我得到了这个工作:

    while member := Paths.current_member().lower():
        sourcefile = f'{Paths.current_source}({member})'
        if myType in exceptions and member in exceptions[myType]:
            logit(f'Skipping {sourcefile}')
            Paths.next_member()
            continue
        logit(f'Retrieving {sourcefile}')
        lines.clear()
        try:
            myFTP.connection.retrlines(f'RETR {member}', lines.append)
        except:
            print(f'Error retrieving {sourcefile}, retrying')
            myFTP.re_connect()        #log back in
            myFTP.connection.cwd(f"'{Paths.current_source}'")
            continue                  #try again

        suffix = suffixes.get(myType, '')
        sep = '.' if suffix else ''
        destfile = f'{Paths.current_dest}/{member}{sep}{suffix}'
        logit(f'Saving to {destfile}')
        fp = open(destfile, 'w',
                encoding='ISO8859-1', errors='backslashreplace')
        line_number = 0
        for line in lines:
            line_number += 1
            bad = [line_number, line]
            line = line.replace('\xdd', '|')
            try:
                fp.write(line.rstrip() + '\n')
            except:
                print(f"line {bad[0]} in {myType} member:",
                      f"{member}{sep}{suffix} - {bad[1]}")
        fp.close()
        Paths.next_member()

myFTP是我创建的一个类,用于存储FTP相关信息,Paths存储源路径和目标路径。我本可以使用一堆全局变量,但我认为这些类更Pythonic。

显然服务器对通过 FTPS 传输的数据量有一些限制,并在一段时间后将其切断。添加重新连接/重试逻辑解决了该问题。

也许这会帮助其他尝试通过 FTPS 实现批量传输的人。

© www.soinside.com 2019 - 2024. All rights reserved.