download_compare/
download_compare.rs1use baidu_netdisk_sdk::BaiduNetDiskClient;
2use log::info;
3use std::path::Path;
4
5const CHUNK_SIZE: u64 = 4 * 1024 * 1024;
6
7#[tokio::main]
8async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
9 env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
10
11 let client = BaiduNetDiskClient::builder().build()?;
12 info!("Client created successfully");
13
14 client.load_token_from_env()?;
15 info!("Token loaded successfully");
16
17 println!("=== Baidu NetDisk Download Comparison Test ===");
18 println!();
19 println!(
20 "Enter the number of threads/concurrency to use (recommended: match your CPU core count)"
21 );
22 println!("Example: 4 for 4 cores, 8 for 8 cores, etc.");
23 let mut input = String::new();
24 std::io::stdin().read_line(&mut input)?;
25 let thread_num: usize = input.trim().parse().unwrap_or(4);
26 let concurrency = thread_num * 3;
27 println!();
28 println!("Thread count: {}", thread_num);
29 println!("Concurrency: {}", concurrency);
30 println!();
31
32 println!("=== Method 1: Streaming (Futures/Concurrency) ===");
33 println!("Enter the remote file path to download:");
34 let mut input = String::new();
35 std::io::stdin().read_line(&mut input)?;
36 let remote_path_streaming = input.trim();
37
38 if remote_path_streaming.is_empty() {
39 eprintln!("Error: File path cannot be empty");
40 return Ok(());
41 }
42
43 println!("\n--- Step 1: Get file info for Streaming ---");
44 let file_info_streaming = client.file().get_file_info(remote_path_streaming).await?;
45 let file_size_streaming = file_info_streaming.size.unwrap_or(0);
46 let fs_id_streaming = file_info_streaming.fs_id.ok_or("File has no fs_id")?;
47 let file_meta_streaming = client.file().get_file_meta(fs_id_streaming).await?;
48
49 println!("File: {}", file_info_streaming.name);
50 println!(
51 "Size: {} bytes ({:.2} MB)",
52 file_size_streaming,
53 file_size_streaming as f64 / (1024.0 * 1024.0)
54 );
55 let total_chunks_streaming = (file_size_streaming + CHUNK_SIZE - 1) / CHUNK_SIZE;
56 println!(
57 "Chunks: {} ({} bytes each)",
58 total_chunks_streaming, CHUNK_SIZE
59 );
60 println!();
61
62 println!("Press Enter to start Streaming download...");
63 std::io::stdin().read_line(&mut String::new())?;
64
65 let streaming_save_path = format!("./download_streaming_{}", file_info_streaming.name);
66 let start_streaming = std::time::Instant::now();
67
68 client
69 .download()
70 .download_streaming_with_meta(
71 &file_meta_streaming,
72 Path::new(&streaming_save_path),
73 concurrency,
74 )
75 .await?;
76
77 let duration_streaming = start_streaming.elapsed();
78 let streaming_mb = file_size_streaming as f64 / (1024.0 * 1024.0);
79 let streaming_sec = duration_streaming.as_secs_f64();
80 let streaming_speed = streaming_mb / streaming_sec;
81
82 println!();
83 println!("=== Method 2: Parallel (Multi-thread) ===");
84 println!("Enter the remote file path to download:");
85 let mut input = String::new();
86 std::io::stdin().read_line(&mut input)?;
87 let remote_path_parallel = input.trim();
88
89 if remote_path_parallel.is_empty() {
90 eprintln!("Error: File path cannot be empty");
91 return Ok(());
92 }
93
94 println!("\n--- Step 1: Get file info for Parallel ---");
95 let file_info_parallel = client.file().get_file_info(remote_path_parallel).await?;
96 let file_size_parallel = file_info_parallel.size.unwrap_or(0);
97 let fs_id_parallel = file_info_parallel.fs_id.ok_or("File has no fs_id")?;
98 let file_meta_parallel = client.file().get_file_meta(fs_id_parallel).await?;
99
100 println!("File: {}", file_info_parallel.name);
101 println!(
102 "Size: {} bytes ({:.2} MB)",
103 file_size_parallel,
104 file_size_parallel as f64 / (1024.0 * 1024.0)
105 );
106 let total_chunks_parallel = (file_size_parallel + CHUNK_SIZE - 1) / CHUNK_SIZE;
107 println!(
108 "Chunks: {} ({} bytes each)",
109 total_chunks_parallel, CHUNK_SIZE
110 );
111 println!();
112
113 println!("Press Enter to start Parallel download...");
114 std::io::stdin().read_line(&mut String::new())?;
115
116 let parallel_save_path = format!("./download_parallel_{}", file_info_parallel.name);
117 let start_parallel = std::time::Instant::now();
118
119 client
120 .download()
121 .download_parallel_multi_threaded(
122 &file_meta_parallel,
123 Path::new(¶llel_save_path),
124 Some(thread_num),
125 )
126 .await?;
127
128 let duration_parallel = start_parallel.elapsed();
129 let parallel_mb = file_size_parallel as f64 / (1024.0 * 1024.0);
130 let parallel_sec = duration_parallel.as_secs_f64();
131 let parallel_speed = parallel_mb / parallel_sec;
132
133 println!();
134 println!("╔══════════════════════════════════════════════════════════════════════════╗");
135 println!("║ DOWNLOAD COMPARISON RESULTS ║");
136 println!("╠══════════════════════════════════════════════════════════════════════════╣");
137 println!(
138 "║ Threads: {} │ Concurrency (Streaming): {} │ ║",
139 thread_num, concurrency
140 );
141 println!("╠══════════════════════════════════════════════════════════════════════════╣");
142 println!("║ Method │ Time │ Speed │ File ║");
143 println!("╠══════════════════════════════════════════════════════════════════════════╣");
144 println!(
145 "║ Streaming (Futures) │ {:>8.2}s │ {:>8.2} MB/s │ {:.15} ║",
146 streaming_sec, streaming_speed, file_info_streaming.name
147 );
148 println!(
149 "║ Parallel (Multi-thread) │ {:>8.2}s │ {:>8.2} MB/s │ {:.15} ║",
150 parallel_sec, parallel_speed, file_info_parallel.name
151 );
152 println!("╠══════════════════════════════════════════════════════════════════════════╣");
153 let speedup = if streaming_sec < parallel_sec {
154 parallel_sec / streaming_sec
155 } else {
156 streaming_sec / parallel_sec
157 };
158 let faster = if streaming_sec < parallel_sec {
159 "Streaming"
160 } else {
161 "Parallel"
162 };
163 println!(
164 "║ Faster: {} ({:.2}x) ║",
165 faster, speedup
166 );
167 println!("╠══════════════════════════════════════════════════════════════════════════╣");
168 println!("║ Note: Parallel mode works best with 6+ cores. On 4 cores, Streaming may ║");
169 println!("║ be 2x faster. Test with your actual core count for best results! ║");
170 println!("╚══════════════════════════════════════════════════════════════════════════╝");
171
172 println!();
173 println!("Output files:");
174 println!(" Parallel: {}", parallel_save_path);
175 println!(" Streaming: {}", streaming_save_path);
176
177 Ok(())
178}