如何在python中上传文件时读取内存中zip文件的内容?

如何在python中上传文件时读取内存中zip文件的内容?,python,django,file,zip,in-memory,Python,Django,File,Zip,In Memory,我有一个zip文件,当用户上传文件时,我会收到该文件。zip基本上包含一个json文件,我希望读取和处理该文件,而无需先创建zip文件,然后解压缩,然后读取内部文件的内容 目前我只做了一个较长的过程,如下所示 import json import zipfile @csrf_exempt def get_zip(request): try: if request.method == "POST": try: cli

我有一个
zip
文件,当用户上传文件时,我会收到该文件。
zip
基本上包含一个
json
文件,我希望读取和处理该文件,而无需先创建
zip
文件,然后解压缩,然后读取内部文件的内容

目前我只做了一个较长的过程,如下所示

import json
import zipfile

@csrf_exempt
def get_zip(request):
    try:
        if request.method == "POST":
            try:
                client_file = request.FILES['file']
                file_path = "/some/path/"
                # first dump the zip file to a directory
                with open(file_path + '%s' % client_file.name, 'wb+') as dest:
                        for chunk in client_file.chunks():
                            dest.write(chunk)

                # unzip the zip file to the same directory 
                with zipfile.ZipFile(file_path + client_file.name, 'r') as zip_ref:
                    zip_ref.extractall(file_path)

                # at this point we get a json file from the zip say `test.json`
                # read the json file content
                with open(file_path + "test.json", "r") as fo:
                    json_content = json.load(fo)
                    doSomething(json_content)
                return HttpResponse(0)

            except Exception as e:
                return HttpResponse(1)
如您所见,这包括3个步骤,最终将内容从
zip
文件获取到内存中。我想要的是获取
zip
文件的内容并直接加载到内存中

我在stack overflow中发现了一些类似的问题,比如这个。但我不确定在什么时候调用这篇文章中提到的操作

我怎样才能做到这一点

注意:我在后端使用django。
zip中总会有一个json文件。

据我所知,@jason想说的是,首先打开一个zipFile,就像您在这里使用zipFile.zipFile(file\u path+client\u file.name,'r')作为zip\u ref:所做的那样

class zipfile.ZipFile(file[, mode[, compression[, allowZip64]]])

  Open a ZIP file, where file can be either a path to a file (a string) or a file-like object.
然后使用读取文件类对象的字节。但从上面看,您是在
r
模式下阅读,而不是在
rb
模式下阅读。因此,请按如下方式更改它

with open(filename, 'rb') as file_data:
    bytes_content = file_data.read()
    file_like_object = io.BytesIO(bytes_content)
    zipfile_ob = zipfile.ZipFile(file_like_object)

现在
zipfile\u ob
可以从内存中访问。

据我所知,@jason试图说的是,首先打开一个zipfile,就像您在这里使用zipfile.zipfile(file\u path+client\u file.name,'r')作为zip\u ref:所做的那样

class zipfile.ZipFile(file[, mode[, compression[, allowZip64]]])

  Open a ZIP file, where file can be either a path to a file (a string) or a file-like object.
然后使用读取文件类对象的字节。但从上面看,您是在
r
模式下阅读,而不是在
rb
模式下阅读。因此,请按如下方式更改它

with open(filename, 'rb') as file_data:
    bytes_content = file_data.read()
    file_like_object = io.BytesIO(bytes_content)
    zipfile_ob = zipfile.ZipFile(file_like_object)

现在可以从内存访问
zipfile\u ob
zipfile.zipfile()
的第一个参数可以是文件对象而不是路径名。我认为Django
UploadedFile
对象支持这种用法,因此您可以直接从中读取,而不必复制到文件中

import json
import zipfile

@csrf_exempt
def get_zip(request):
    try:
        if request.method == "POST":
            try:
                client_file = request.FILES['file']
                # unzip the zip file to the same directory 
                with zipfile.ZipFile(client_file, 'r') as zip_ref:
                    first = zip_ref.infolist()[0]
                    with zip_ref.open(first, "r") as fo:
                        json_content = json.load(fo)
                doSomething(json_content)
                return HttpResponse(0)

            except Exception as e:
                return HttpResponse(1)
您还可以直接从zip存档打开文件,而不是将其解压缩到文件中

import json
import zipfile

@csrf_exempt
def get_zip(request):
    try:
        if request.method == "POST":
            try:
                client_file = request.FILES['file']
                # unzip the zip file to the same directory 
                with zipfile.ZipFile(client_file, 'r') as zip_ref:
                    first = zip_ref.infolist()[0]
                    with zip_ref.open(first, "r") as fo:
                        json_content = json.load(fo)
                doSomething(json_content)
                return HttpResponse(0)

            except Exception as e:
                return HttpResponse(1)

zipfile.zipfile()
的第一个参数可以是文件对象,而不是路径名。我认为Django
UploadedFile
对象支持这种用法,因此您可以直接从中读取,而不必复制到文件中

import json
import zipfile

@csrf_exempt
def get_zip(request):
    try:
        if request.method == "POST":
            try:
                client_file = request.FILES['file']
                # unzip the zip file to the same directory 
                with zipfile.ZipFile(client_file, 'r') as zip_ref:
                    first = zip_ref.infolist()[0]
                    with zip_ref.open(first, "r") as fo:
                        json_content = json.load(fo)
                doSomething(json_content)
                return HttpResponse(0)

            except Exception as e:
                return HttpResponse(1)
您还可以直接从zip存档打开文件,而不是将其解压缩到文件中

import json
import zipfile

@csrf_exempt
def get_zip(request):
    try:
        if request.method == "POST":
            try:
                client_file = request.FILES['file']
                # unzip the zip file to the same directory 
                with zipfile.ZipFile(client_file, 'r') as zip_ref:
                    first = zip_ref.infolist()[0]
                    with zip_ref.open(first, "r") as fo:
                        json_content = json.load(fo)
                doSomething(json_content)
                return HttpResponse(0)

            except Exception as e:
                return HttpResponse(1)

谢谢你,伙计!这正是我想要的。节省了我一些不必要的步骤。谢谢你,伙计!这正是我想要的。节省了我一些不必要的步骤。非常感谢,io.BytesIO()为我工作了很多,io.BytesIO()为我工作了很多