Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PythonZipFile,对文件数量的奇怪限制:“;文件夹无效";_Python_Zipfile - Fatal编程技术网

PythonZipFile,对文件数量的奇怪限制:“;文件夹无效";

PythonZipFile,对文件数量的奇怪限制:“;文件夹无效";,python,zipfile,Python,Zipfile,电脑在玩弄我,我知道 我正在用Python创建一个zip文件夹。单个文件在内存中生成,然后整个文件被压缩并保存到一个文件中。我可以添加9个文件到zip。我被允许向zip添加11个文件。但是10个,不,不是10个文件。zip文件保存到我的计算机上,但不允许我打开它;Windows表示压缩的压缩文件夹无效 我使用下面的代码,这是我从另一个stackoverflow问题中得到的。它附加10个文件并保存压缩文件夹。当我点击文件夹时,我无法提取它。但是,去掉其中一个附件()就可以了。或者,添加另一个附加,

电脑在玩弄我,我知道

我正在用Python创建一个zip文件夹。单个文件在内存中生成,然后整个文件被压缩并保存到一个文件中。我可以添加9个文件到zip。我被允许向zip添加11个文件。但是10个,不,不是10个文件。zip文件保存到我的计算机上,但不允许我打开它;Windows表示压缩的压缩文件夹无效

我使用下面的代码,这是我从另一个stackoverflow问题中得到的。它附加10个文件并保存压缩文件夹。当我点击文件夹时,我无法提取它。但是,去掉其中一个附件()就可以了。或者,添加另一个附加,它就工作了

我错过了什么?我怎样才能每次都做到这一点

imz = InMemoryZip() 
imz.append("1a.txt", "a").append("2a.txt", "a").append("3a.txt", "a").append("4a.txt", "a").append("5a.txt", "a").append("6a.txt", "a").append("7a.txt", "a").append("8a.txt", "a").append("9a.txt", "a").append("10a.txt", "a")
imz.writetofile("C:/path/test.zip") 


import zipfile
import StringIO
class InMemoryZip(object):
    def __init__(self):
        # Create the in-memory file-like object
        self.in_memory_zip = StringIO.StringIO()

    def append(self, filename_in_zip, file_contents):
        '''Appends a file with name filename_in_zip and contents of 
        file_contents to the in-memory zip.'''
        # Get a handle to the in-memory zip in append mode
        zf = zipfile.ZipFile(self.in_memory_zip, "a", zipfile.ZIP_DEFLATED, False)

        # Write the file to the in-memory zip
        zf.writestr(filename_in_zip, file_contents)

        # Mark the files as having been created on Windows so that
        # Unix permissions are not inferred as 0000
        for zfile in zf.filelist:
            zfile.create_system = 0        

        return self

    def read(self):
        '''Returns a string with the contents of the in-memory zip.'''
        self.in_memory_zip.seek(0)
        return self.in_memory_zip.read()

    def writetofile(self, filename):
        '''Writes the in-memory zip to a file.'''
        f = file(filename, "w")
        f.write(self.read())
        f.close()

创建要保存到文件系统的文件时,应使用“wb”模式。这将确保文件以二进制形式写入

否则,在zip文件中遇到换行符(\n)时,python将替换它以匹配windows行结尾(\r\n)。10个文件出现问题的原因是10恰好是\n的代码

因此,您的写入函数应该如下所示:

def writetofile(self, filename):
    '''Writes the in-memory zip to a file.'''
    f = file(filename, 'wb')
    f.write(self.read())
    f.close()
这将解决您的问题,并适用于示例中的文件。尽管如此,在您的情况下,您可能会发现将zip文件直接写入文件系统更容易,如下面的代码所示,其中包括上面的一些注释:

import StringIO
import zipfile

class ZipCreator:
    buffer = None

    def __init__(self, fileName=None):
        if fileName:
            self.zipFile = zipfile.ZipFile(fileName, 'w', zipfile.ZIP_DEFLATED, False)
            return

        self.buffer = StringIO.StringIO()
        self.zipFile = zipfile.ZipFile(self.buffer, 'w', zipfile.ZIP_DEFLATED, False)

    def addToZipFromFileSystem(self, filePath, filenameInZip):
        self.zipFile.write(filePath, filenameInZip)

    def addToZipFromMemory(self, filenameInZip, fileContents):
        self.zipFile.writestr(filenameInZip, fileContents)

        for zipFile in self.zipFile.filelist:
            zipFile.create_system = 0

    def write(self, fileName):            
        if not self.buffer:  # If the buffer was not initialized the file is written by the ZipFile
            self.zipFile.close()
            return

        f = file(fileName, 'wb')
        f.write(self.buffer.getvalue())
        f.close()

# Use File Handle
zipCreator = ZipCreator('C:/path/test.zip')

# Use Memory Buffer
# zipCreator = ZipCreator()

for i in range(1, 10):
    zipCreator.addToZipFromMemory('test/%sa.txt' % i, 'a')

zipCreator.write('C:/path/test.zip')

理想情况下,您可能会对内存中的zip和从一开始就绑定到文件系统的zip使用单独的类。在添加文件夹时,内存中的zip似乎也出现了一些问题,这些文件夹很难重新创建,我仍在努力查找。

hmm。。尝试重新使用相同的
ZipFile
实例,而不是每次都创建一个新实例。尝试使用
zf.close()
将ZipFile.ZipFile(…)作为zf:
-您当前的代码依赖垃圾收集将数据刷新到内存中的文件。此代码没有意义<创建
imz
时,code>InMemoryZip不存在。谢谢。根据您的评论,我将考虑重写代码。