feat: 添加文件上传进度跟踪功能,支持实时显示上传速度和剩余时间

This commit is contained in:
Yakumo Hokori
2025-12-11 23:12:45 +08:00
parent ab635e19eb
commit 0c69355c5a
11 changed files with 815 additions and 15 deletions

78
examples/basic_usage.rs Normal file
View File

@@ -0,0 +1,78 @@
// 这个示例展示了如何使用UPFS库的基本功能
// 包括上传文件和进度跟踪
// 由于示例是独立的我们需要通过cargo run --example来运行
// 这会自动链接到库
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("UPFS 基本使用示例");
println!("=================");
// 创建一个测试文件
std::fs::write("test_upload.txt", "这是一个测试文件\n用于演示上传功能")?;
// 模拟token实际使用中需要通过登录获取
let token = "Bearer test-token".to_string();
let file_path = "test_upload.txt";
let remote_path = "/demo/test.txt";
println!("准备上传文件: {}", file_path);
println!("远程路径: {}", remote_path);
println!();
// 演示1: 使用进度回调上传
println!("演示1: 带进度跟踪的上传");
println!("----------------------------");
let start_time = std::time::Instant::now();
// 这里使用简单的进度回调
match upfs::update::upload_file_with_progress(
token.clone(),
file_path,
remote_path,
|progress| {
if progress.percentage <= 100.0 {
print!("\r\x1b[K进度: {:.1}% ({}/{}) - {} - {}",
progress.percentage,
format_bytes(progress.bytes_uploaded),
format_bytes(progress.total_bytes),
progress.format_speed(),
progress.format_remaining_time()
);
}
std::io::Write::flush(&mut std::io::stdout()).unwrap();
}
).await {
Ok(response) => {
println!("\n✅ 上传成功!");
println!("状态码: {}", response.status);
println!("响应: {}", response.text);
println!("总用时: {:?}", start_time.elapsed());
}
Err(e) => {
println!("\n❌ 上传失败: {}", e);
}
}
println!();
println!("演示完成!");
// 清理测试文件
std::fs::remove_file("test_upload.txt").ok();
Ok(())
}
fn format_bytes(bytes: u64) -> String {
if bytes < 1024 {
format!("{} B", bytes)
} else if bytes < 1024 * 1024 {
format!("{:.1} KB", bytes as f64 / 1024.0)
} else if bytes < 1024 * 1024 * 1024 {
format!("{:.1} MB", bytes as f64 / (1024.0 * 1024.0))
} else {
format!("{:.1} GB", bytes as f64 / (1024.0 * 1024.0 * 1024.0))
}
}

78
examples/progress_demo.rs Normal file
View File

@@ -0,0 +1,78 @@
use upfs::update::{upload_file_with_progress, UploadProgress};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("🔥 上传进度跟踪演示");
println!("================");
// 模拟登录获取token (这里使用一个假的token)
let token = "Bearer fake-token-for-demo".to_string();
let file_path = "test_file.txt";
let remote_path = "/demo/progress_test.txt";
// 设置进度回调函数
let progress_callback = |progress: UploadProgress| {
print_progress(&progress);
};
println!("开始上传: {} -> {}", file_path, remote_path);
println!("进度条说明: [进度百分比] | 上传速度 | 已用时间 | 剩余时间 | 已上传/总大小");
println!();
// 上传文件并显示进度
match upload_file_with_progress(token, file_path, remote_path, progress_callback).await {
Ok(response) => {
println!("\n✅ 上传完成!");
println!("服务器状态: {}", response.status);
println!("服务器响应: {}", response.text);
}
Err(e) => {
println!("\n❌ 上传失败: {}", e);
}
}
Ok(())
}
// 显示进度的函数
fn print_progress(progress: &UploadProgress) {
print!("\r[");
let bar_width = 30;
let filled = (progress.percentage / 100.0 * bar_width as f64) as usize;
for i in 0..bar_width {
if i < filled {
print!("=");
} else if i == filled {
print!(">");
} else {
print!(" ");
}
}
print!("] {:.1}% | {} | {} | {}",
progress.percentage,
progress.format_speed(),
progress.format_elapsed_time(),
progress.format_remaining_time()
);
print!(" | {}/{}",
format_bytes(progress.bytes_uploaded),
progress.format_bytes()
);
std::io::Write::flush(&mut std::io::stdout()).unwrap();
}
fn format_bytes(bytes: u64) -> String {
if bytes < 1024 {
format!("{} B", bytes)
} else if bytes < 1024 * 1024 {
format!("{:.2} KB", bytes as f64 / 1024.0)
} else if bytes < 1024 * 1024 * 1024 {
format!("{:.2} MB", bytes as f64 / (1024.0 * 1024.0))
} else {
format!("{:.2} GB", bytes as f64 / (1024.0 * 1024.0 * 1024.0))
}
}