Rust文件清单生成库simple-file-manifest的使用,高效生成和管理文件目录结构的工具
simple-file-manifest
这个crate提供了一个存储无关的接口,用于表示文件集合。它允许您构建文件列表,这些文件由路径名和内容+元数据组成。内容可以由引用的文件支持或在内存中定义。
元数据
pkg:cargo/simple-file-manifest@0.11.0 近3年前 2021版本 MIT OR Apache-2.0 11.7 KiB
安装
在您的项目目录中运行以下Cargo命令: cargo add simple-file-manifest
或者将以下行添加到您的Cargo.toml中: simple-file-manifest = “0.11.0”
文档 docs.rs/simple-file-manifest/0.11.0
代码仓库 github.com/indygreg/simple-file-manifest-rs
所有者 Gregory Szorc
内容中提供的示例:
use simple_file_manifest::FileManifest;
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建一个新的文件清单
let mut manifest = FileManifest::default();
// 添加内存中的文件内容
manifest.add_file(
"README.md", // 文件名
"This is a sample readme file".as_bytes(), // 文件内容
)?;
// 添加来自文件系统的文件
manifest.add_file_from_path(
"src/main.rs", // 在清单中的路径
Path::new("src/main.rs"), // 实际文件路径
)?;
// 迭代清单中的所有文件
for entry in manifest.iter() {
println!("File: {}", entry.path());
println!("Size: {} bytes", entry.data().len());
}
// 将清单写入tar归档文件
let mut tar_data = Vec::new();
manifest.write_tar(&mut tar_data)?;
println!("Generated tar archive with {} bytes", tar_data.len());
Ok(())
}
完整示例demo:
use simple_file_manifest::FileManifest;
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 创建一个新的文件清单
let mut manifest = FileManifest::default();
// 添加内存中的文件内容
manifest.add_file(
"README.md", // 文件名
"This is a sample readme file".as_bytes(), // 文件内容
)?;
// 添加来自文件系统的文件
manifest.add_file_from_path(
"src/main.rs", // 在清单中的路径
Path::new("src/main.rs"), // 实际文件路径
)?;
// 迭代清单中的所有文件
for entry in manifest.iter() {
println!("File: {}", entry.path());
println!("Size: {} bytes", entry.data().len());
}
// 将清单写入tar归档文件
let mut tar_data = Vec::new();
manifest.write_tar(&mut tar_data)?;
println!("Generated tar archive with {} bytes", tar_data.len());
Ok(())
}
1 回复
simple-file-manifest:高效生成和管理文件目录结构的Rust库
概述
simple-file-manifest是一个轻量级的Rust库,专门用于生成和管理文件目录清单。它能够递归扫描指定目录,生成包含文件路径、大小、修改时间等元数据的结构化清单,支持多种输出格式。
主要特性
- 递归目录扫描
- 支持JSON、TOML、YAML等多种输出格式
- 可配置的元数据包含选项
- 排除特定文件或目录
- 计算文件哈希值(可选)
安装方法
在Cargo.toml中添加依赖:
[dependencies]
simple-file-manifest = "0.2"
基本用法
生成目录清单
use simple_file_manifest::FileManifest;
fn main() -> std::io::Result<()> {
let manifest = FileManifest::new("./src")?
.generate()?;
println!("{}", manifest.to_json_pretty()?);
Ok(())
}
配置选项示例
use simple_file_manifest::{FileManifest, ManifestConfig};
fn main() -> std::io::Result<()> {
let config = ManifestConfig {
include_file_size: true,
include_modified_time: true,
include_hash: true,
exclude_patterns: vec!["*.tmp".to_string(), "temp/".to_string()],
..Default::default()
};
let manifest = FileManifest::with_config("./project", config)?
.generate()?;
// 保存为JSON文件
manifest.to_json_file("manifest.json")?;
Ok(())
}
读取和使用清单
use simple_file_manifest::FileManifest;
fn load_and_use_manifest() -> std::io::Result<()> {
let manifest = FileManifest::from_json_file("manifest.json")?;
for entry in manifest.entries() {
println!("文件: {}, 大小: {} bytes",
entry.path().display(),
entry.size().unwrap_or(0));
}
Ok(())
}
高级用法
自定义筛选器
use simple_file_manifest::{FileManifest, FileEntry};
fn custom_filter() -> std::io::Result<()> {
let manifest = FileManifest::new("./src")?
.generate_with_filter(|entry: &FileEntry| {
// 只包含Rust源文件且大于1KB的文件
entry.path().extension().map(|ext| ext == "rs").unwrap_or(false)
&& entry.size().unwrap_or(0) > 1024
})?;
println!("筛选后的文件数量: {}", manifest.entries().len());
Ok(())
}
比较两个清单
use simple_file_manifest::{FileManifest, ManifestDiff};
fn compare_manifests() -> std::io::Result<()> {
let old_manifest = FileManifest::from_json_file("old_manifest.json")?;
let new_manifest = FileManifest::from_json_file("new_manifest.json")?;
let diff = ManifestDiff::compare(&old_manifest, &new_manifest);
println!("新增文件: {:?}", diff.added_files());
println!("删除文件: {:?}", diff.removed_files());
println!("修改文件: {:?}", diff.modified_files());
Ok(())
}
错误处理
use simple_file_manifest::FileManifest;
fn handle_errors() -> Result<(), Box<dyn std::error::Error>> {
match FileManifest::new("/nonexistent/path") {
Ok(manifest) => {
let result = manifest.generate()?;
println!("成功生成清单: {}个文件", result.entries().len());
}
Err(e) => eprintln!("错误: {}", e),
}
Ok(())
}
性能提示
- 对于大型目录,考虑使用异步版本
- 启用
include_hash
会显著影响性能,仅在需要时使用 - 使用排除模式减少不必要的文件处理
这个库特别适合用于备份验证、文件同步、变更检测等场景,提供了简单易用的API来处理文件目录结构。
完整示例demo
// 完整示例:使用simple-file-manifest库生成、保存、读取和比较文件清单
use simple_file_manifest::{FileManifest, ManifestConfig, FileEntry, ManifestDiff};
use std::io::Result;
fn main() -> Result<()> {
// 示例1:基本用法 - 生成目录清单并输出JSON
println!("=== 基本用法示例 ===");
let manifest = FileManifest::new("./src")?
.generate()?;
println!("生成的JSON清单:");
println!("{}", manifest.to_json_pretty()?);
// 示例2:配置选项 - 包含更多元数据并排除特定文件
println!("\n=== 配置选项示例 ===");
let config = ManifestConfig {
include_file_size: true,
include_modified_time: true,
include_hash: true, // 注意:启用哈希计算会影响性能
exclude_patterns: vec!["*.tmp".to_string(), "target/".to_string()],
..Default::default()
};
let detailed_manifest = FileManifest::with_config(".", config)?
.generate()?;
// 保存为JSON文件
detailed_manifest.to_json_file("detailed_manifest.json")?;
println!("详细清单已保存到 detailed_manifest.json");
// 示例3:读取和使用清单文件
println!("\n=== 读取清单示例 ===");
let loaded_manifest = FileManifest::from_json_file("detailed_manifest.json")?;
println!("清单中包含的文件:");
for entry in loaded_manifest.entries() {
println!("- {} ({} bytes)",
entry.path().display(),
entry.size().unwrap_or(0));
}
// 示例4:自定义筛选器 - 只处理特定文件
println!("\n=== 自定义筛选器示例 ===");
let filtered_manifest = FileManifest::new(".")?
.generate_with_filter(|entry: &FileEntry| {
// 只包含Rust文件且小于100KB的文件
entry.path().extension().map(|ext| ext == "rs").unwrap_or(false)
&& entry.size().unwrap_or(0) < 100 * 1024
})?;
println!("筛选后的Rust文件数量: {}", filtered_manifest.entries().len());
// 示例5:比较两个清单(模拟场景)
println!("\n=== 清单比较示例 ===");
// 假设我们有两个不同时间点的清单
let old_files = detailed_manifest;
let new_files = filtered_manifest;
let diff = ManifestDiff::compare(&old_files, &new_files);
println!("比较结果:");
println!("新增文件: {:?}", diff.added_files().len());
println!("删除文件: {:?}", diff.removed_files().len());
println!("修改文件: {:?}", diff.modified_files().len());
// 示例6:错误处理
println!("\n=== 错误处理示例 ===");
match FileManifest::new("/不存在的路径") {
Ok(manifest) => {
let result = manifest.generate()?;
println!("成功生成清单: {}个文件", result.entries().len());
}
Err(e) => println!("预期中的错误: {}", e),
}
Ok(())
}
// 异步版本示例(需要启用异步特性)
#[cfg(feature = "async")]
async fn async_example() -> Result<()> {
use simple_file_manifest::AsyncFileManifest;
let manifest = AsyncFileManifest::new("./large_directory").await?
.generate().await?;
println!("异步生成的清单: {}个文件", manifest.entries().len());
Ok(())
}
这个完整示例展示了simple-file-manifest库的主要功能:
- 基本目录扫描和JSON输出
- 配置元数据选项和排除模式
- 从文件读取清单数据
- 使用自定义筛选器处理特定文件
- 比较两个文件清单的差异
- 错误处理的最佳实践
- 异步用法的示例(需要启用异步特性)
使用时请确保在Cargo.toml中添加了正确的依赖,并根据实际需求调整配置参数。