【问题标题】:Python 3.5: Tarfile append mode "ReadError" on empty tarPython 3.5:空 tar 上的 Tarfile 附加模式“ReadError”
【发布时间】:2017-07-28 14:30:22
【问题描述】:

我在使用最新的 python 3.5 包及其tarfile 模块创建新的 tar 文件时遇到了问题。这个问题类似于herehere 讨论的问题。在前一种情况下,建议的解决方案会返回错误ReadError: empty header,而在后一种情况下,这是八年前的一个封闭问题,应该已经通过加载最新版本的语言来应用该补丁。 Tarfile 模块的文档明确指出“a”可用于创建新的 tarfile。

在尝试创建新的 tar 文件时会特别出现该问题。生成它的代码在下面完整复制;我用来在多处理中对任务进行基准测试的简单脚本。

#just a little script to test copy times for a control

import os
import os.path
import time
import shutil
import multiprocessing
import tarfile

global source; source = "/home/patches/Documents/Scripting Projects/Resources/Test Payload"
global dest; dest = "/home/patches/Desktop/Copy Benchmark 
Output.tar.bz2"
global start
global end
global diff
global testing; testing = True
global numConsumers; numConsumers = multiprocessing.cpu_count()


#Classes!
class copyProc(multiprocessing.Process):
    def __init__(self, qTask):
        multiprocessing.Process.__init__(self)
        self.qTask = qTask
        os.chdir(source)

    def run(self):
        proc_name = self.name
        while True:
            next_task = self.qTask.get()
            if next_task is None:
                # Poison pill means shutdown
                print('%s: Exiting' % proc_name)
                self.qTask.task_done()
                break
            next_task()
            self.qTask.task_done()
        return

class copyJob(object):
    def __init__(self, a):
        self.tgt = a
    def __call__(self):
        tar = tarfile.open(dest, "a")
        tar.add(self.tgt)
        tar.close()

#Function
def announce():
    print("Starting copy benchmark - multiprocessing.")
    foo = input("Press any key to begin")

def startTimer():
    global start
    start = time.time()


def setup():
    os.chdir(source)
    for a, b, files in os.walk(source):
        for file in files:
        tasks.put(copyJob(file))
    for i in range(numConsumers):
        tasks.put(None)

def endTimer():
    global end
    end = time.time()

def prompt():
    diff = end - start
#   os.remove(dest)
    print("The test took %s seconds" % str(diff))
    bar = input("Run again? Y/n")
    if bar == "n":
        testing = False

#runtime
if __name__ == '__main__':
    multiprocessing.set_start_method("spawn")
    tasks = multiprocessing.JoinableQueue()
    announce()
    startTimer()
    setup()
consumers = []
for i in range(numConsumers):
    consumers.append(copyProc(tasks))
for w in consumers:
    w.start()
tasks.join()
endTimer()
prompt()

编辑添加:具体问题在于,脚本在尝试打开 tar 文件时抛出“ReadError: empty header”异常,而不是特定行为。

【问题讨论】:

  • 问题出在哪里?
  • 是的,你是对的,明确这一点会有所帮助。我已经修改了这个问题。具体问题就在底部。

标签: python-3.x tarfile


【解决方案1】:

事实证明,问题在于多个进程试图或多或少地同时打开文件会导致问题。解决方案是使用某种形式的锁定来防止这种情况发生。

在我的例子中,我使用了一个简单的 multiprocessing.Lock() 对象,并让进程在附加之前获取它,然后再释放它。此解决方案仍然比在单个进程中执行所有附加要快。不知道为什么。

如果您像我一样遇到这个问题,我希望这个解决方案也适合您。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    • 2012-12-30
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多