从z/os下载Python和ftplib.FTP的文本文件

Bre*_*ugh 5 python ftp mainframe zos

我正在尝试使用Python和ftplib自动从az/os PDS下载一些文本文件.

由于主机文件是EBCDIC,我不能简单地使用FTP.retrbinary().

FTP.retrlines()当与open(file,w).writelines一起用作其回调时,当然不提供EOL.

所以,对于初学者来说,我已经提出了这段"看起来对我好"的代码,但由于我是一个相对的Python noob,有人能提出更好的方法吗?显然,为了保持这个简单的问题,这不是最后的,钟声和口哨的事情.

非常感谢.

#!python.exe
from ftplib import FTP

class xfile (file):
    def writelineswitheol(self, sequence):
        for s in sequence:
            self.write(s+"\r\n")

sess = FTP("zos.server.to.be", "myid", "mypassword")
sess.sendcmd("site sbd=(IBM-1047,ISO8859-1)")
sess.cwd("'FOO.BAR.PDS'")
a = sess.nlst("RTB*")
for i in a:
    sess.retrlines("RETR "+i, xfile(i, 'w').writelineswitheol)
sess.quit()
Run Code Online (Sandbox Code Playgroud)

更新:Python 3.0,平台是Windows XP下的MingW.

z/os PDS具有固定的记录结构,而不是依赖行结尾作为记录分隔符.但是,z/os FTP服务器在文本模式下传输时,会提供记录结尾,其后退()剥离.

结账更新:

这是我修改后的解决方案,它将成为持续开发的基础(例如,删除内置密码):

import ftplib
import os
from sys import exc_info

sess = ftplib.FTP("undisclosed.server.com", "userid", "password")
sess.sendcmd("site sbd=(IBM-1047,ISO8859-1)")
for dir in ["ASM", "ASML", "ASMM", "C", "CPP", "DLLA", "DLLC", "DLMC", "GEN", "HDR", "MAC"]:
    sess.cwd("'ZLTALM.PREP.%s'" % dir)
    try:
        filelist = sess.nlst()
    except ftplib.error_perm as x:
        if (x.args[0][:3] != '550'):
            raise
    else:
        try:
            os.mkdir(dir)
        except:
            continue
        for hostfile in filelist:
            lines = []
            sess.retrlines("RETR "+hostfile, lines.append)
            pcfile = open("%s/%s"% (dir,hostfile), 'w')
            for line in lines:
                pcfile.write(line+"\n")
            pcfile.close()
        print ("Done: " + dir)
sess.quit()
Run Code Online (Sandbox Code Playgroud)

我要感谢John和Vinay

Dav*_*ths 5

刚刚遇到这个问题,因为我试图弄清楚如何从 z/OS 递归下载数据集。多年来,我一直在使用一个简单的 python 脚本从大型机下载 ebcdic 文件。它有效地做到了这一点:

def writeline(line):
    file.write(line + "\n")

file = open(filename, "w")
ftp.retrlines("retr " + filename, writeline)
Run Code Online (Sandbox Code Playgroud)