سؤال

أحاول أتمتة تنزيل بعض الملفات النصية من AZ / OS PDS، باستخدام Python و FTPLIB.

نظرا لأن الملفات المضيفة هي ebcdic، لا يمكنني ببساطة استخدام ftp.retrbinary ().

FTP.retrlines ()، عند استخدامها مع فتح (ملف، ث) .WRITELINES كعناصر رد، لا توفر، بالطبع، EOLs.

لذلك، بالنسبة للمبتدئين، لقد جاءت مع هذه القطعة التي "تبدو جيدة بالنسبة لي"، ولكن لأنني 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()

تحديث: Python 3.0، النظام الأساسي هو Mingw تحت نظام التشغيل Windows XP.

Z / OS PDSs لديها بنية سجل ثابتة، بدلا من الاعتماد على النهايات على الإنترنت كمفصل سجل. ومع ذلك، يوفر خادم 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()

شكر من كل من جون و فيناي

هل كانت مفيدة؟

المحلول

جاءت للتو عبر هذا السؤال كما كنت أحاول معرفة كيفية تنزيل مجموعات البيانات بشكل متكرر من Z / OS. لقد كنت أستخدم نص Python بسيط لسنوات الآن لتنزيل ملفات EBCDIC من المركزية. انها فعالة فقط يفعل هذا:

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

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

نصائح أخرى

يجب أن تكون قادرا على تنزيل الملف كثنائي (باستخدام retrbinary) واستخدام codecs وحدة للتحويل من EBCDIC إلى أي ترميز الإخراج الذي تريده. يجب أن تعرف صفحة رمز EBCDIC المحددة المستخدمة في نظام Z / OS (مثل 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 سيكون الخط، وسوف تكتب حلقة الخاص بك أحرف فردية في الخط إلى الإخراج، كل على خطها الخاص. وبعد لذلك ربما تريد أن تفعل self.write(sequence + "\r\n") بدلا من for حلقه. لا يزال لا يشعر بشكل خاص بالحق في الفئة الفرعية file فقط لإضافة طريقة الأداة المساعدة هذه، على الرغم من ذلك - ربما يجب أن تكون في فئة مختلفة في حياتك bells-and-whistles الإصدار.

طريقة Writelineswitheol الخاصة بك إلحاق " r n" بدلا من " n" ثم يكتب النتيجة إلى ملف مفتوح في وضع النص. التأثير، بغض النظر عن النظام الأساسي الذي تقوم بتشغيله، سيكون " r" غير مرغوب فيه. مجرد إلحاق " n" وستحصل على النهاية المناسبة.

لا ينبغي إلغاء معالجة الأخطاء الصحيحة إلى إصدار "أجراس وصفارات". يجب عليك إعداد رد اتصالك بحيث يتم فتح ملفك () في محاولة / ما عدا وتحتفظ بإشارة إلى مؤشر ملفات الإخراج، تتمثل مكالمة الكتابة الخاصة بك في محاولة / ما عدا، ولديها طريقة CallBack_obj.Close () التي يمكنك استخدامها عند إعادة الملتقطة () إلى File_handle.Close بشكل صريح. يمكنك حفظ الحاجة إلى التفكير في متى سيتم إغلاق ملفاتك ضمنيا وما إذا كنت تخاطر بالتنفد من مقابض الملفات.

يجب أن يمنحك Python 3.x ftplib.ftp.retrlines () كائنات STR في تأثير سلاسل Unicode، وستحتاج إلى تشفيرها قبل أن تكتبها - ما لم يكن الترميز الافتراضي هو اللاتينية 1 والتي ستكون غير عادية إلى حد ما لنظام التشغيل Windows صندوق. يجب أن يكون لديك ملفات اختبار مع (1) كل ما هو ممكن 256 بايت (2) جميع البايتات الصحيحة في شفرة EBCDIC المتوقعة.

ملاحظات قليلة "الصرف الصحي"

  1. يجب أن تفكر في ترقية بيثون الخاص بك من الإصدار 3.0 (دليل "إثبات") إلى 3.1.

  2. لتسهيل فهم أفضل لكودك، استخدم "I" كمعرف فقط كوسيط تسلسل وفقط إذا كنت قد اكتسبت عادة عادة من Fortran 3 أو أكثر من العقود :-)

  3. اثنان من المشكلات المكتشفة حتى الآن (إلحاق الخطوط الإلهية إلى كل حرف، المنهي خط خاطئ) قد أظهرت لأول مرة قمت باختبارها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top