为什么没有文件内容被复制到我的tarfile中

时间:2017-10-29 20:55:58

标签: python

这里有一些代码用于将zipfile的内容复制到tarfile。我打算稍后将复制限制为出现在作为进一步参数传入的列表中的文件,但是现在,我只是试图复制工作。

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"是一个包含两个小文本文件的zip文件,a.txt和b.txt,每个文件包含大约15个字符。显然它还包含这些的mac备份," _a.txt"和" _b.txt"同样(虽然当我使用Archive实用程序扩展它时,那些不会出现,即使使用" ls -al")。

执行后(Python 2.7.10),还有一个附加文件" tarfile.tar&#34 ;;当我在Mac上使用Archive实用程序打开它时,我看到了:

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

执行期间创建的临时文件实际上包含15个左右的愚蠢文本字符,但tar文件中的文件是零长度。

所以我的问题是"为什么tar文件包含0长度版本的a.txt和b.txt?"

2 个答案:

答案 0 :(得分:0)

临时文件可能尚未完全刷新。

您可以尝试: temp.flush() os.fsync()

但当然最好不要首先创建临时文件。您可以使用tar.addfile代替tar.add来避免这种情况。

您还需要设置您提供的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")

答案 1 :(得分: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)

秘诀在于临时结束前的一行。事实证明,您无法将一个打开的文件添加到tar存档(尽管文档似乎没有提到)。