在Django中使用zipfile模块实现对上传的zip压缩包提取文件名

文章介绍了如何在Python中使用zipfile模块处理ZIP压缩包,包括解压文件获取带路径和不带路径的文件名,以及不解压压缩包直接获取文件名的方法。同时,针对中文乱码问题,提供了编码转换的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

方法一:解压zip压缩包

思路一:获取带相对路径的文件名

思路二:只获取文件名(不带路径)

方法二:不解压压缩包(推荐)

思路一:获取带相对路径的文件名

思路二:只获取文件名(不带路径)

中文乱码的处理

方式一:解压压缩包(不带路径)

方式二:解压压缩包(带相对路径)


需要使用到zipfile标准模块

方法一:解压zip压缩包

思路一:获取带相对路径的文件名
import zipfile
import os


class UnZip(View):
    def post(self, request):
        # 处理zip压缩包文件
        zip_file = request.FILES.get('file')  # 获取上传的zip压缩包

        # 方式二:思路一:将文件解压出来并遍历目录下的文件(带文件路径)
        extract_folder = zip_file.name.split('.')[0]  # 获取不带后缀名压缩包文件名
        zip_file = zipfile.ZipFile(zip_file)

        # 将文件解压到文件夹
        zip_file.extractall(path=extract_folder)
        zip_file.close()  # 关闭

        file_list = []
        
        # 遍历读取已解压的文件夹里的文件
        for root, dirs, files in os.walk(extract_folder + '/' + extract_folder + '/'):
            for file in files:
                # 因为解压出来的文件里会带自动带有一个desktop.ini文件,所以在这里获取时把这个文件给过滤掉
                if file == "desktop.ini":
                    continue
                # 这里使用.encode('cp437').decode('gbk')对file文件名进行中文名处理,否则中文会是乱码
                file_path = os.path.join(root, file.encode('cp437').decode('gbk'))
                file_list.append(file_path)
        return JsonResponse({"rest": file_list})
思路二:只获取文件名(不带路径)
import zipfile
import os


class UnZip(View):
    def post(self, request):
        # 处理zip压缩包文件
        zip_file = request.FILES.get('file')  # 获取zip压缩包

        extract_folder = zip_file.name.split('.')[0]
        zip_file = zipfile.ZipFile(zip_file)

        # 将文件解压到zip文件夹
        zip_file.extractall(path=extract_folder)
        zip_file.close()

        # 方式二:思路二:将文件解压出来并遍历目录下的文件(不带文件路径,只有文件名)
        file_names = []
        for root, dirs, files in os.walk(extract_folder + '/' + extract_folder + '/'):
            for file in files:
                if file == "desktop.ini":
                    continue
                # 使用.encode('cp437').decode('gbk')对中文文件名进行处理
                file_name = os.path.basename(file.encode('cp437').decode('gbk'))
                file_names.append(file_name)
        return JsonResponse({"rest": file_names})  # 返回所有文件名

方法二:不解压压缩包(推荐)

思路一:获取带相对路径的文件名
import zipfile

class UnZip(View):
    def post(self, request):
        # 处理zip压缩包文件
        zip_file = request.FILES.get('file')  # 获取zip压缩包

        # 方式一:不解压压缩包
        zip_names = []
        with zipfile.ZipFile(zip_file, 'r') as zipobj:
            # 思路一:带路径的
            for file_name in zipobj.namelist():
                # 对空文件名和自动生成的desktop.ini文件进行过滤
                if file_name.split('/')[-1] == '' or file_name.split('/')[-1] == "desktop.ini":
                    continue
                zip_names.append(file_name.encode('cp437').decode('gbk'))
    return JsonResponse({"res": zip_names})
思路二:只获取文件名(不带路径)
import zipfile


class UnZip(View):
    def compare_lists(self, list1, list2):
        """校对zip与excel数据是否匹配,输出不匹配和匹配的文件名"""
        set1 = set(list1)
        set2 = set(list2)

        different_elements = list(set1.symmetric_difference(set2))
        common_elements = list(set1.intersection(set2))

        diff_list1 = [element for element in different_elements if element in list1]
        diff_list2 = [element for element in different_elements if element in list2]

        return diff_list1, diff_list2, common_elements

    def post(self, request):
        # 处理zip压缩包文件
        zip_file = request.FILES.get('file')  # 获取zip压缩包

        # 方式一:不解压压缩包
        zip_names = []
        with zipfile.ZipFile(zip_file, 'r') as zipobj:
            # 思路二:不带路径的
            for file_info in zipobj.infolist():
                file_name = file_info.filename.split('/')[-1]  # 获取不带路径的文件名
                # 对空文件名和自动生成的desktop.ini进去过滤处理
                if file_name == '' or file_name == 'desktop.ini':
                    continue
                else:
                    zip_names.append(file_name.encode('cp437').decode('gbk'))
        return JsonResponse({"res": zip_names})

中文乱码的处理

由于上面方法一中解压压缩包时遇到中文文件名时会出现文件名是乱码的问题,所以给出这个方法,方法参考:解决Python中ZipFile解压文件名中文乱码的问题_python解压zip文件出现乱码文件名_i止于至善的博客-CSDN博客

方式一:解压压缩包(不带路径)
from zipfile import ZipFile
import os
class UnZip(View):
    def post(self, request):
        # 处理zip压缩包文件
        zip_file = request.FILES.get('file')  # 获取zip压缩包

        def support_gbk(zip_file):
            """对中文文件名处理编码处理,防止乱码"""
            name_to_info = zip_file.NameToInfo
            # copy map first
            for name, info in name_to_info.copy().items():
                real_name = name.encode('cp437').decode('gbk')
                if real_name != name:
                    info.filename = real_name
                    del name_to_info[name]
                    name_to_info[real_name] = info
            return zip_file

        extract_folder = zip_file.name.split('.')[0]

        # 将文件解压到zip文件夹
        with support_gbk(ZipFile(zip_file)) as zip_ref:
            zip_ref.extractall(path=extract_folder, pwd=None)


        # 方式二:思路二:将文件解压出来并遍历目录下的文件(不带文件路径,只有文件名)
        file_names = []
        for root, dirs, files in os.walk(extract_folder + '/' + extract_folder + '/'):
            for file in files:
                if file == "desktop.ini":
                    continue
                file_name = os.path.basename(file)
                file_names.append(file_name)
        return JsonResponse({"rest": file_names})  # 返回所有文件名
方式二:解压压缩包(带相对路径)
from zipfile import ZipFile
import os
class UnZip(View):
    def post(self, request):
        # 处理zip压缩包文件
        zip_file = request.FILES.get('file')  # 获取zip压缩包

        def support_gbk(zip_file):
            """对中文文件名处理编码处理,防止乱码"""
            name_to_info = zip_file.NameToInfo
            # copy map first
            for name, info in name_to_info.copy().items():
                real_name = name.encode('cp437').decode('gbk')
                if real_name != name:
                    info.filename = real_name
                    del name_to_info[name]
                    name_to_info[real_name] = info
            return zip_file

        extract_folder = zip_file.name.split('.')[0]

        # 将文件解压到zip文件夹
        with support_gbk(ZipFile(zip_file)) as zip_ref:
            zip_ref.extractall(path=extract_folder, pwd=None)


        file_list = []

        for root, dirs, files in os.walk(extract_folder + '/' + extract_folder + '/'):
            for file in files:
                if file == "desktop.ini":
                    continue
                file_path = os.path.join(root, file)
                file_list.append(file_path)
        return JsonResponse({"rest": file_list})

Django实现文件的ZIP打包并提供下载功能,可以按照以下步骤操作: 1. **创建ZIP文件**: 使用Python标准库`zipfile`模块创建一个ZIP文件。首先,你需要选择要压缩到ZIP里的文件或目录列表。例如,你可以从用户的请求获取文件路径。 ```python import zipfile from io import BytesIO def create_zip_package(file_list): zip_buffer = BytesIO() with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file: for file in file_list: zip_file.write(file) return zip_buffer.getvalue() ``` 2. **响应处理**: 创建完ZIP包后,需要将其转换为HTTP响应,设置正确的Content-Type和Content-Disposition头信息以便于浏览器识别并下载。你可以使用`HttpResponse`来完成这个任务。 ```python from django.http import HttpResponse def download_zip(request): file_list = get_files_to_compress() # 获取需要压缩的文件列表 zip_data = create_zip_package(file_list) response = HttpResponse(zip_data, content_type='application/zip') response['Content-Disposition'] = f'attachment; filename="files.zip"' return response ``` 3. **URL配置**: 将上述函数添加到Django应用的视图中,并配置URL,让用户通过访问特定URL下载ZIP文件。 在`urls.py`中,你可以像下面这样配置: ```python from django.urls import path from . import views urlpatterns = [ path('download/', views.download_zip, name='download_zip'), ] ``` 现在,当用户访问`/download/`时,将会下载名为`files.zip`的ZIP文件,其中包含你指定的文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

湿透剪自布

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值