rust 异步zip解压缩

在使用actix-web框架的时候,如果使用zip解压任务将会占用一个工作线程,因为zip库是同步阻塞的,想用异步非阻塞需要用另一个库,下面列出同步解压,跟异步解压的两个方法实现,异步解压不会占用工作线程。

阻塞解压

依赖库

zip = "0.6.6"

rust代码

pub fn unzip<P: AsRef<std::path::Path>>(
    file_path: P,
    unzip_path: P,
) -> Result<(), std::io::Error> {
    let file_path = file_path.as_ref();
    let unzip_path = unzip_path.as_ref();
    let unzip_path = std::path::Path::new(unzip_path);
    if unzip_path.exists() {
        std::fs::remove_dir_all(unzip_path)?;
    } else {
        std::fs::create_dir_all(unzip_path)?;
    }
    let file = std::fs::File::open(file_path)?;
    let mut archive = zip::ZipArchive::new(file)?;
    for index in 0..archive.len() {
        let mut file = archive.by_index(index)?;
        let file_name = file.mangled_name();
        let outpath = unzip_path.join(file_name);
        if file.is_dir() {
            std::fs::create_dir_all(&outpath)?;
        } else {
            if let Some(p) = outpath.parent() {
                if !p.exists() {
                    std::fs::create_dir_all(p)?;
                }
            }
            let mut outfile = std::fs::File::create(&outpath)?;
            std::io::copy(&mut file, &mut outfile)?;
        }
    }
    return Ok(());
}

异步解压

依赖库

async_zip = { version = "0.0.17", features = ["tokio", "tokio-fs", "deflate"] }
futures-lite = "2.3.0"
tokio = { version = "1.35.1", features = ["macros"] }
tokio-util = "0.7.10"

rust代码

use async_zip::base::read::seek::ZipFileReader;
use async_zip::base::write::ZipFileWriter;
use async_zip::ZipEntryBuilder;
use tokio::fs::OpenOptions;
use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};

pub async fn unzip_async<P: AsRef<std::path::Path>>(
    file_path: P,
    unzip_path: P,
) -> Result<(), ApiError> {
    let unzip_path = unzip_path.as_ref();
    if unzip_path.exists() {
        std::fs::remove_dir_all(unzip_path)?;
    } else {
        std::fs::create_dir_all(unzip_path)?;
    }
    let file = tokio::fs::File::open(file_path.as_ref()).await?;
    let reader = tokio::io::BufReader::new(file);
    let mut zip = ZipFileReader::with_tokio(reader)
        .await
        .map_err(ApiError::from)?;
    for index in 0..zip.file().entries().len() {
        let entry = zip
            .file()
            .entries()
            .get(index)
            .ok_or(ApiError::msg("zip entry not found"))?;
        let raw = entry.filename().as_bytes();
        let mut file_name = &String::from_utf8_lossy(raw).to_string(); //必需转换为utf8,不能使用自带的,会乱码
        let outpath = unzip_path.join(file_name);
        if file_name.ends_with("/") {
            tokio::fs::create_dir_all(&outpath).await?;
        } else {
            if let Some(p) = outpath.parent() {
                if !p.exists() {
                    tokio::fs::create_dir_all(p).await?;
                }
            }
            let mut entry_reader = zip
                .reader_without_entry(index)
                .await
                .map_err(ApiError::from)?;
            let mut writer = OpenOptions::new()
                .write(true)
                .create_new(true)
                .open(&outpath)
                .await
                .map_err(ApiError::from)?;
            futures_lite::io::copy(&mut entry_reader, &mut writer.compat_write()).await?;
        }
    }
    Ok(())
}

相关推荐

  1. rust 异步zip压缩

    2024-04-08 11:50:03       38 阅读
  2. zip压缩

    2024-04-08 11:50:03       50 阅读
  3. c# Zip压缩压缩

    2024-04-08 11:50:03       53 阅读
  4. rust - 对文件进行zip压缩加密

    2024-04-08 11:50:03       46 阅读
  5. rust - 对文件夹进行zip压缩加密

    2024-04-08 11:50:03       56 阅读
  6. 7-Zip压缩软件功能介绍

    2024-04-08 11:50:03       35 阅读
  7. Linux-压缩文件命令(gzip、zip、unzip、tar、jar)

    2024-04-08 11:50:03       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-08 11:50:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-08 11:50:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-08 11:50:03       87 阅读
  4. Python语言-面向对象

    2024-04-08 11:50:03       96 阅读

热门阅读

  1. C++面试100问与自动驾驶100问

    2024-04-08 11:50:03       43 阅读
  2. IJKPLAYER源码分析-AudioTrack播放

    2024-04-08 11:50:03       36 阅读
  3. MongoDB聚合运算符:$minN

    2024-04-08 11:50:03       40 阅读
  4. SqlServer 全文索引

    2024-04-08 11:50:03       36 阅读
  5. HTML:HTML事件汇总

    2024-04-08 11:50:03       35 阅读
  6. Linux Shell:用户配置文件详解

    2024-04-08 11:50:03       36 阅读
  7. MySQL:表的约束(上)

    2024-04-08 11:50:03       35 阅读
  8. 【软设】知识点速记2

    2024-04-08 11:50:03       35 阅读
  9. ffmpeg处理视频命令

    2024-04-08 11:50:03       29 阅读