1

Python の ftplib を使用して、リモート FTP サイトから zip ファイルを FTP 送信しています。次に、それをディスクに書き込もうとします。ファイルの書き込みは機能しますが、WinZip または WinRar を使用して zip を開こうとするほとんどの試みは失敗します。どちらのアプリも、ファイルが破損していると主張しています。ただし、奇妙なことに、右クリックして WinRar を使用してファイルを抽出しようとすると、ファイル抽出されます。

明確にするために、ファイルの書き込みは機能しますが、一般的な zip アプリ内で開くことはできませんが、同じアプリを使用して解凍します。Python zipfile モジュールは、zip の抽出に失敗することはありません。

FTP サイトから zip ファイルを取得するために使用しているコードを次に示します (不適切なタブは無視してください。それは問題ではありません)。

filedata = None
def appender(chunk):
    global filedata
    filedata += chunk


def getfile(filename):
  try:
      ftp = None

      try:
          ftp = FTP(address)
          ftp.login('user', 'password')

      except Exception, e:
          print e

      command = 'RETR ' + filename

      idx = filename.rfind('/')
      path = filename[0:idx]
      ftp.cwd(path)
      fileonly = filename[idx+1:len(filename)]

      ftp.retrbinary('RETR ' + filename, appender)

      global filedata
      data = filedata

      ftp.close()

      filedata = ''
      return data

  except Exception, e:
      print e

data = getfile('/archives/myfile.zip')    
file = open(pathtoNTFileShare, 'wb')
file.write(data)
file.close()
4

2 に答える 2

2

アペンダーを渡す代わりに、retrbinary 関数内で file.write を直接渡します。これは機能し、大きなファイルをダウンロードするときに RAM をあまり使用しません。

ただし、データを変数内に保存したい場合は、次の名前の変数を使用することもできます。

blocks = []

次に、appender の代わりに retrbinary に渡します。

blocks.append

現在のアペンダー機能が間違っています。+= は、文字列の追加を試み、最初の NULL で停止するため、バイナリ データがある場合は正しく機能しません。

@Lee B で述べたように、urllib2 または Curl も使用できます。しかし、上記の小さな変更を加えれば、現在のコードはほぼ正しいものになります。

于 2009-02-23T01:13:59.353 に答える
1

私はそのライブラリを使用したことがありませんが、urllib2 は問題なく動作し、より簡単です。カールはさらに良いです。

あなたのコードを見ると、いくつか間違っていることがわかります。例外をキャッチすると、例外が出力されるだけで、続行されます。FTP 接続を取得できないなどの致命的なエラーの場合、メッセージを出力してから終了する必要があります。また、filedata は None として始まり、アペンダーは += を使用してそれに追加するため、文字列 + None を追加しようとしています。ここで試してみると TypeError が返されます。まったく機能していることに驚いています。アペンダーが例外をスローし、FTP コピーが異常終了するだろうと推測していたでしょう。

読み直しているうちに、バイナリ データでの += の使用に関する別の回答に気付きました。それだけかもしれません。python は時々スマートになろうとし、空白や NUL などを含む文字列を結合するときに「役立つ」可能性があります。あなたの最善の策は、ファイルを開いて(outfileと呼びましょう)、アペンダーを使用してoutfile.write(chunk)だけにすることです。

于 2009-02-23T01:12:00.437 に答える