Rust生成Zip文件在macOS打开报Error 0未定义错误排查
问题分析与修复方案
问题根源
- 打包了正在生成的Zip文件:你在目标目录下创建
archive.zip后,立刻遍历该目录,会把这个还在写入的Zip文件也加入归档,直接破坏了Zip文件的结构,这是报错的核心原因。 - 未创建目录条目:macOS归档工具对Zip格式的目录结构要求严格,仅添加文件而不显式创建目录条目,可能导致识别异常。
修复后的代码
use std::{path::Path, fs::File}; use zip::{ZipWriter, write::FileOptions}; fn main() { // 定义Zip文件路径 let zip_file_path = "/Users/xiaoqiangjiang/source/reddwarf/backend/texhub-server/archive.zip"; let file = File::create(zip_file_path).unwrap(); let mut zip = ZipWriter::new(file); let folder_path = Path::new("/Users/xiaoqiangjiang/source/reddwarf/backend/texhub-server"); visit_folder(folder_path, &mut zip, "", zip_file_path).unwrap(); zip.finish().unwrap(); } fn visit_folder( path: &Path, zip: &mut ZipWriter<File>, parent: &str, exclude_path: &str ) -> std::io::Result<()> { let current_dir_name = path.file_name().unwrap().to_string_lossy(); // 生成当前目录在Zip中的路径 let current_zip_dir = if parent.is_empty() { current_dir_name.to_string() } else { format!("{}/{}", parent, current_dir_name) }; // 显式创建当前目录的Zip条目 zip.add_directory(current_zip_dir.as_str(), FileOptions::default())?; for entry in path.read_dir()? { let entry = entry?; let file_path = entry.path(); // 跳过正在生成的Zip文件 if file_path.to_string_lossy() == exclude_path { continue; } let file_name = file_path.file_name().unwrap().to_string_lossy().into_owned(); let zip_path = format!("{}/{}", current_zip_dir, file_name); if file_path.is_dir() { visit_folder(&file_path, zip, ¤t_zip_dir, exclude_path)?; } else { let mut file = File::open(&file_path)?; let options = FileOptions::default() .compression_method(zip::CompressionMethod::Deflated) .unix_permissions(0o755); zip.start_file(zip_path, options)?; std::io::copy(&mut file, zip)?; } } Ok(()) }
额外优化建议
- 避免自打包:可以直接把Zip文件输出到目标目录之外,比如
/Users/xiaoqiangjiang/source/reddwarf/backend/archive.zip,从根源上避免打包自身的问题。 - 升级依赖库:将
zip库升级到最新稳定版(当前为0.7.x),新版对格式兼容性更好,API更完善。修改Cargo.toml中的依赖:
zip = "0.7"
内容的提问来源于stack exchange,提问作者Dolphin
相关产品推荐
相关产品推荐

