2009-07-26 4 views
3

Python 및 ftplib을 사용하여 z/os PDS에서 일부 텍스트 파일 다운로드를 자동화하려고합니다.z/o에서 Python 및 ftplib.FTP로 텍스트 파일 다운로드

호스트 파일이 EBCDIC이기 때문에 단순히 FTP.retrbinary()를 사용할 수 없습니다.

콜백으로 open (file, w) .writelines와 함께 사용되는 FTP.retrlines()는 물론 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() 

업데이트 : 플랫폼은 Windows XP에서 MingW입니다.

z/os PDS는 줄 끝을 레코드 구분 기호로 사용하지 않고 고정 된 레코드 구조를 가지고 있습니다. 그러나 z/os FTP 서버는 텍스트 모드로 전송할 때 retrlines()가 제거되는 레코드 결말을 제공합니다.

닫기 갱신 : 존과 모두

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

내 감사 : 여기

(예를 들어, 제거 내장 된 암호) 지속적인 개발을위한 기초가 될 것입니다 내 수정 된 솔루션입니다 Vinay

+0

질문을 편집하고 PDS 파일을 설명하십시오. "일부 텍스트 파일"은 다소 부적합합니다. –

+0

또한 어떤 플랫폼, 어떤 Python 버전 및 writelineswitheol 메서드가 '\ n'대신 '\ r \ n'을 추가하는지 알려주십시오. 그리고 실제로 이것을 실행했는지 여부를 명시하고 출력 결과를 점검하여 플랫폼에 올바른 회선 종단 처리가 이루어 졌는지 확인하십시오. –

+0

완료. 나는 주말에 corp.firewall 밖에서 집에서 코딩을하고 있기 때문에 이번 주말에 그 아이디어를 테스트 할 것입니다. –

답변

3

z/OS에서 재귀 적으로 데이터 세트를 다운로드하는 방법을 알아 내려고했던이 질문을 직접 살펴 보았습니다. 나는 메인 프레임에서 ebcdic 파일을 다운로드하기 위해 수년간 간단한 파이썬 스크립트를 사용 해왔다. 실제로이 작업을 수행합니다.

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

file = open(filename, "w") 
ftp.retrlines("retr " + filename, writeline) 
3

retrbinary을 사용하여 파일을 다운로드하고 codecs 모듈을 사용하여 EBCDIC을 어떤 출력 인코딩으로 변환 할 수 있어야합니다. 필요. z/OS 시스템에서 사용되는 특정 EBCDIC 코드 페이지 (예 : cp500)를 알아야합니다. 파일이 작은 경우 (UTF-8로 변환)과 같이 할도 수 :

file = open(ebcdic_filename, "rb") 
data = file.read() 
converted = data.decode("cp500").encode("utf8") 
file = open(utf8_filename, "wb") 
file.write(converted) 
file.close() 

업데이트 : 당신은 라인과 라인에 돌아 오는 얻을 retrlines를 사용해야하는 경우 콜백은 각 행에 대해 한 번 호출되므로 올바른 인코딩을 사용하면 접근 방식이 작동하지 않습니다. 따라서 콜백에서 sequence은 줄이되고 for 루프는 줄의 개별 문자를 각각의 줄에에 출력합니다. 따라서 for 루프가 아닌 self.write(sequence + "\r\n")을 수행하려고합니다. 그래도 여전히 file 하위 클래스로이 유틸리티 메소드를 추가하는 것이 좋지는 않습니다. bells-and-whistles 버전의 다른 클래스에 있어야 할 것입니다.

+0

감사합니다. Vinay, 흥미로운 아이디어입니다.하지만 어떻게 개행을 삽입합니까? (이들은 OpenEdition 파일이 아닌 일반적인 zos PDS입니다.) –

+0

EBCDIC 줄 바꿈이 아닌 경우 호스트 시스템에서 줄이 어떻게 종료됩니까? –

+1

호스트 파일 시스템이 레코드 기반입니다. 길이가 고정 길이이거나 모든 레코드의 길이가 같거나 가변 길이 인 경우 길이는 각 레코드의 시작 부분에 설명자 필드에 저장됩니다. FTP.retrlines()는 레코드를 올바르게 추출하지만 줄 바꿈을 제공하지는 않는다. –

1

writelineswitheol 메서드는 '\ n'대신 '\ r \ n'을 추가 한 다음 텍스트 모드로 열린 파일에 결과를 씁니다. 이 효과는 실행중인 플랫폼에 관계없이 원하지 않는 '\ r'이됩니다. '\ n'을 추가하면 적절한 줄이 끝납니다.

올바른 오류 처리를 "종소리와 호각"버전으로 강요해서는 안됩니다. open() 파일이 try/except에 있고 출력 파일 핸들에 대한 참조를 유지하고 콜백 호출이 try/except에 있고 콜백 _obj.close() 메소드가있는 콜백을 설정해야합니다. retrlines()가 명시 적으로 file_handle.close() (try/except)에서 리턴 할 때 사용한다.메시지 "는 X 파일 Y를 닫을 수 없으므로 파일을 암시 적으로 닫을 때 및 파일 핸들이 부족할 위험이 있는지 생각할 필요가 없습니다.

파이썬 3.x ftplib.FTP.retrlines()는 사실 유니 코드 문자열 인 str 객체를 제공해야하며, 쓰기 전에 반드시 인코딩해야합니다. 기본 인코딩은 latin1이 아니라면 윈도우 박스에서는 드물다. 예상되는 EBCDIC 코드 페이지에서 유효한 모든 256 바이트 (2) 모든 바이트로 (1) 테스트 파일을 가져야합니다.

[몇 "위생"발언]

  1. 당신은 3.1 3.0에서 (는 "증거 개념의"릴리스) 파이썬 업그레이드를 고려해야합니다.

  2. 코드의 이해를 용이하게하려면, 사용하는 "나"만 시퀀스 인덱스 등 만이 irredeemably FORTRAN 3 전 더 수십 년의 :-)

  3. 두에서 습관을 구입 한 경우 식별자로 지금까지 발견 된 문제점 (각 문자에 행 종결 자 추가, 잘못된 행 종결 자)은 처음 테스트했을 때 나타났습니다.

+0

John, 고맙습니다. 나는 당신의 정당한 비난을 받아 들였음을 확신합니다. –