2017-10-29 7 views
1

zipファイルの内容をtarfileにコピーするためのコードです。私は後で、さらなる引数として渡されるリスト内に現れるファイルにコピーを制限しようとしていますが、今はコピー作業をしようとしています。ファイルの内容がtarファイルにコピーされないのはなぜですか?

import zipfile, tempfile, shutil, tarfile, os 

def gather_and_repackage_files(zip_file_path, target_file_path) : 
    with tarfile.open(target_file_path, "w") as tar: 
     with zipfile.ZipFile(zip_file_path) as zip_file: 
      for member in zip_file.namelist(): 
       filename = os.path.basename(member) 
       # skip directories 
       if not filename: 
        continue 

       print "File: ", filename 
       # copy file (taken from zipfile's extract) 
       source = zip_file.open(member) 
       with tempfile.NamedTemporaryFile(delete=False) as temp: 
        print temp.name 
        shutil.copyfileobj(source, temp) 
        tar.add(temp.name, arcname=filename) 


gather_and_repackage_files("./stuff.zip", "./tarfile.tar") 

これを実行する前に、私のディレクトリの内容は "testin.py"(上記のプログラム)と "stuff.zip"です。 "stuff.zip"は、a.txtとb.txtの2つの小さなテキストファイルを含むzipファイルです。各ファイルには約15文字が含まれています。どうやらそれはまた、 "_a.txt"と "_b.txt"というMacのバックアップも含んでいます(アーカイブユーティリティで展開しても、 "ls -al"でさえも表示されません)。

実行後(Python 2.7.10)には、追加のファイル "tarfile.tar"があります。実行中に作成された一時ファイルが実際に愚かなテキストの15かそこらの文字が含まれているんが、tarファイル内のものはゼロいる

drwx------ 6 jfh staff 204 Oct 29 16:51 . 
drwxr-xr-x 7 jfh staff 238 Oct 29 16:51 .. 
-rw------- 1 jfh staff 0 Oct 29 16:50 ._a.txt 
-rw------- 1 jfh staff 0 Oct 29 16:50 ._b.txt 
-rw------- 1 jfh staff 0 Oct 29 16:50 a.txt 
-rw------- 1 jfh staff 0 Oct 29 16:50 b.txt 

:私は私のMac上のアーカイブユーティリティでこれを開くと、私はこれを参照してください長さ

私の質問は、なぜtarファイルにはa.txtとb.txtの長さが0のバージョンが含まれているのですか?

+0

'shutil.copyfileobj(source、temp)'動作すると非常に驚くでしょう。 zipファイルを扱うために直接使用することができますか? – HuStmpHrrr

+0

その部分はうまくいくようです - 私は一時ファイルを見ました( "delete = False"であることに注意してください)。 – John

答えて

0

一時ファイルが完全にフラッシュされていない可能性があります。

あなたはに試みることができる: temp.flush() os.fsync()

しかし、もちろん、最初の場所に一時ファイルを作成しない方が良いでしょう。 tar.addの代わりにtar.addfileを使用すると回避できます。

また、提供するtarinfoのサイズを設定する必要があります。

注:時間を保存するようにmtimeを設定することもできます。

この変更は、それを行う必要があります。ここでは

import zipfile 
import tarfile 
import os 

def gather_and_repackage_files(zip_file_path, target_file_path) : 
    with tarfile.open(target_file_path, "w") as tar: 
     with zipfile.ZipFile(zip_file_path) as zip_file: 
      for info in zip_file.infolist(): 
       filename = os.path.basename(info.filename) 
       # skip directories 
       if not filename: 
        continue 

       # copy file (taken from zipfile's extract) 
       with zip_file.open(info) as source: 
        tarinfo = tarfile.TarInfo(filename) 
        tarinfo.size = info.file_size 
        tar.addfile(tarinfo, source) 


gather_and_repackage_files("./stuff.zip", "./tarfile.tar") 
+0

最後の行の「Tarinfo」はTarInfoである必要がありますが、それでも私は長さ0のファイルa.txtとb.txtを取得します。 – John

+0

@John apologies、typoを修正しました。また、サイズの人口を追加しました。 – de1

0

は、コードを働いている:

import zipfile, tempfile, shutil, tarfile, os 

def gather_and_repackage_files(zip_file_path, target_file_path) : 
    with tarfile.open(target_file_path, "w") as tar: 
     with zipfile.ZipFile(zip_file_path) as zip_file: 
      for member in zip_file.namelist(): 
       filename = os.path.basename(member) 
       # skip directories 
       if not filename: 
        continue 

       print "File: ", filename 
       print "Member: ", member 
       source = zip_file.open(member) 
       with tempfile.NamedTemporaryFile(delete=False) as temp: 
        print temp.name 

        shutil.copyfileobj(source, temp) 

        temp.close() 
        tar.add(temp.name, arcname=filename) 

秘密のソースは、終了前に 'temp.close()'、1行です。開いているファイルをtarアーカイブに追加することはできないことが分かりましたが(ドキュメンテーションにはそれは言及されていませんが)

関連する問題