zipファイルをダウンロードするとPythonでディスクに書き込むに特別なトリックはありますか?
質問
私は、Pythonのftplibのを使用して、リモートFTPサイトからzipファイルをFTPingています。私は、それをディスクに書き込みを試みます。ファイル書き込みの作品は、しかし、ほとんどのWinZipやWinRarのは失敗使用してzipファイルを開こうとします。両方のアプリケーションは、ファイルが破損していると主張します。右、ファイルをクリックし、WinRarのを使用してファイルを抽出しようとしたときに奇妙なことが、ののエキスます。
意志だから、明確にするために、ファイルの書き込みは動作しますが、しません。のオープンの人気のzipのアプリの内部が、のは、同じアプリケーションを使用して解凍します。 Pythonの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()
解決
の代わりにアペンダを渡すのretrbinary関数の内部file.write直接渡します。これは動作しますし、あなたは大きなファイルをダウンロードしているとき、それはまた、多くのRAMを使用しません。
あなたがが変数内に格納されたデータが欲しい場合は、あなたもという名前の変数を持つことができます:
blocks = []
次に、アペンダの代わりretrbinaryに渡す
blocks.append
あなたの現在のアペンダ機能が間違っています。それは、文字列の追加]を実行しようと、それは見て最初のNULLで停止しますので、バイナリデータがあるときに+ =正常に動作しません。
@Lee Bで述べたように、あなたはまた、urllib2のか、カールを使用することができます。あなたは、私が上記の小さな変更を加えた場合でも、あなたの現在のコードはほとんど正しいです。
他のヒント
私はそのライブラリを使用していないが、urllib2の正常に動作し、かつ、より簡単です決してきました。カールはさらに良いです。
あなたのコードを見て、私は間違って物事のカップルを見ることができます。唯一のキャッチあなたの例外が例外を出力し、その後続けています。 FTP接続が届かないなどの致命的なエラーのために、彼らはメッセージして終了を印刷する必要があります。また、あなたのfiledataには、あなたのアペンダはそれに追加する= +使用して、該当なしとオフを開始するので、あなたは、私はここにそれを試してはTypeErrorを与える文字列+なしに、追加しようとしています。私はそれがすべてで働いて驚いています。私は、アペンダは例外をスローし、そのためFTPコピーが中止だろうと推測しているでしょう。
再読みながら、私は、バイナリデータの+の使用=について別の答えに気づきました。それは十分にそれである可能性があります。 Pythonは時々、スマートにしよう、とあなたは空白やNULsその中、またはそのような何かを持つ文字列を結合する際に「助けて」することができます。あなたの最善の策は、(のは、それをOUTFILE呼びましょう)開いているファイルを持っている、とだけoutfile.write(チャンク)にあなたのアペンダを使用することがあります。