pub struct UploadClient { /* private fields */ }Expand description
Upload client for Baidu NetDisk
Implementations§
Source§impl UploadClient
impl UploadClient
Sourcepub fn new(http_client: HttpClient, token_getter: Arc<dyn TokenGetter>) -> Self
pub fn new(http_client: HttpClient, token_getter: Arc<dyn TokenGetter>) -> Self
Create a new UploadClient instance
Usually you don’t need to call this directly - use BaiduNetDiskClient::upload() instead.
Sourcepub fn http_client(&self) -> &HttpClient
pub fn http_client(&self) -> &HttpClient
Get a reference to the internal HTTP client
Sourcepub async fn precreate(
&self,
options: PrecreateOptions,
) -> NetDiskResult<PrecreateResponse>
pub async fn precreate( &self, options: PrecreateOptions, ) -> NetDiskResult<PrecreateResponse>
Precreate an upload session
Initiates an upload session and checks which chunks (if any) already exist on the server. This is the first step of the multi-step upload process.
Examples found in repository?
43async fn main() -> Result<(), Box<dyn std::error::Error>> {
44 env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
45
46 let client = BaiduNetDiskClient::builder().build()?;
47 info!("Client created successfully");
48
49 client.load_token_from_env()?;
50 info!("Token loaded successfully");
51
52 let args: Vec<String> = std::env::args().collect();
53
54 if args.len() < 3 {
55 println!("Usage: {} <local_file> <remote_path>", args[0]);
56 println!("Example: {} test.txt /apps/test/test.txt", args[0]);
57 return Ok(());
58 }
59
60 let local_file = &args[1];
61 let remote_path = &args[2];
62
63 println!("=== Baidu NetDisk Preupload Test ===");
64 println!("Local file: {}", local_file);
65 println!("Remote path: {}", remote_path);
66 println!();
67
68 let (file_size, block_list) = get_file_md5blocks(local_file, 4 * 1024 * 1024)?;
69 let file_md5 = calculate_md5(local_file)?;
70
71 println!("File size: {} bytes", file_size);
72 println!("File MD5: {}", file_md5);
73 println!("Block count: {}", block_list.len());
74 println!("Block list: {:?}", block_list);
75 println!();
76
77 let options = PrecreateOptions::new(remote_path, file_size, block_list)
78 .content_md5(&file_md5)
79 .rtype(1);
80
81 println!("Sending precreate request...");
82 match client.upload().precreate(options).await {
83 Ok(response) => {
84 println!("Precreate success!");
85 println!(" Upload ID: {}", response.uploadid);
86 println!(" Path: {:?}", response.path);
87 println!(" Return type: {}", response.return_type);
88 println!(" Block list to upload: {:?}", response.block_list);
89 }
90 Err(e) => {
91 println!("Precreate failed: {}", e);
92 }
93 }
94
95 Ok(())
96}Source§impl UploadClient
impl UploadClient
Sourcepub async fn locate_upload(
&self,
path: &str,
uploadid: &str,
) -> NetDiskResult<LocateUploadResponse>
pub async fn locate_upload( &self, path: &str, uploadid: &str, ) -> NetDiskResult<LocateUploadResponse>
Locate upload domain
Gets the upload domain before uploading chunks. This is required before uploading file data.
According to Baidu NetDisk API documentation, the servers are sorted by proximity and speed. The first server is recommended as the default choice for optimal upload performance.
§Example
use baidu_netdisk_sdk::BaiduNetDiskClient;
let client = BaiduNetDiskClient::builder().build()?;
client.load_token_from_env()?;
let response = client.upload()
.locate_upload("/apps/appName/filename.jpg", "P1-MTAuMjI4LjQzLjMxOjE1OTU4NTg==")
.await?;
// Get the first HTTPS server (recommended by Baidu for optimal performance)
if let Some(server) = response.get_first_https_server() {
println!("Upload server: {}", server);
}Sourcepub async fn upload_chunk(
&self,
options: UploadChunkOptions,
server_url: Option<&str>,
) -> NetDiskResult<UploadChunkResponse>
pub async fn upload_chunk( &self, options: UploadChunkOptions, server_url: Option<&str>, ) -> NetDiskResult<UploadChunkResponse>
Upload a single chunk
If server_url is not provided, the default server https://c3.pcs.baidu.com will be used.
Sourcepub async fn upload_chunks_parallel(
&self,
remote_path: &str,
uploadid: &str,
chunks: Vec<(u32, Vec<u8>)>,
max_concurrency: usize,
server_url: Option<&str>,
) -> NetDiskResult<Vec<(u32, String)>>
pub async fn upload_chunks_parallel( &self, remote_path: &str, uploadid: &str, chunks: Vec<(u32, Vec<u8>)>, max_concurrency: usize, server_url: Option<&str>, ) -> NetDiskResult<Vec<(u32, String)>>
Upload multiple chunks in parallel
If server_url is not provided, the default server https://c3.pcs.baidu.com will be used.
Sourcepub async fn create_file(
&self,
options: CreateFileOptions,
) -> NetDiskResult<CreateFileResponse>
pub async fn create_file( &self, options: CreateFileOptions, ) -> NetDiskResult<CreateFileResponse>
Create the final file on the server
This is the final step of the upload process, which merges all uploaded chunks into a single file.
Source§impl UploadClient
impl UploadClient
Sourcepub async fn upload_file<P: AsRef<Path>>(
&self,
local_path: P,
remote_path: &str,
) -> NetDiskResult<CreateFileResponse>
pub async fn upload_file<P: AsRef<Path>>( &self, local_path: P, remote_path: &str, ) -> NetDiskResult<CreateFileResponse>
Upload a file from local path (simple API)
This is the simplest way to upload a file. It handles everything automatically:
- Opens and reads the file
- Calculates MD5 for each chunk
- Uploads missing chunks in parallel
- Creates the final file on the server
§Example
use baidu_netdisk_sdk::BaiduNetDiskClient;
let client = BaiduNetDiskClient::builder().build()?;
client.load_token_from_env()?;
let response = client.upload()
.upload_file("test.txt", "/remote/test.txt")
.await?;
println!("Uploaded: {} ({} bytes)", response.path, response.size);§See Also
UploadClient::upload_file_with_optionsfor custom chunk size and concurrencyUploadClient::upload_readerfor streaming upload with custom readersUploadClient::upload_bytesfor uploading data already in memory
Examples found in repository?
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6 env_logger::init();
7
8 let client = BaiduNetDiskClient::builder().build()?;
9 info!("Client created successfully");
10
11 client.load_token_from_env()?;
12 info!("Token loaded successfully");
13
14 let args: Vec<String> = std::env::args().collect();
15
16 if args.len() < 3 {
17 println!("Usage: {} <local_file> <remote_path>", args[0]);
18 println!("Example: {} test.txt /apps/test/test.txt", args[0]);
19 return Ok(());
20 }
21
22 let local_file = &args[1];
23 let remote_path = &args[2];
24
25 println!("=== Baidu NetDisk File Upload (Simple) ===");
26 println!("Local file: {}", local_file);
27 println!("Remote path: {}", remote_path);
28 println!();
29
30 let start_time = std::time::Instant::now();
31
32 let response = client.upload().upload_file(local_file, remote_path).await?;
33
34 println!("File uploaded successfully!");
35 println!(" FS ID: {}", response.fs_id);
36 println!(" Server filename: {:?}", response.server_filename);
37 println!(" Path: {}", response.path);
38 println!(" Size: {} bytes", response.size);
39 println!(" Category: {}", response.category);
40 println!(" MD5: {}", response.md5.unwrap_or_default());
41 println!(" Upload time: {:?}", start_time.elapsed());
42
43 Ok(())
44}Sourcepub async fn upload_file_with_options<P: AsRef<Path>>(
&self,
local_path: P,
remote_path: &str,
options: SimpleUploadOptions,
) -> NetDiskResult<CreateFileResponse>
pub async fn upload_file_with_options<P: AsRef<Path>>( &self, local_path: P, remote_path: &str, options: SimpleUploadOptions, ) -> NetDiskResult<CreateFileResponse>
Upload a file from local path with custom options
Use this method to customize upload behavior:
chunk_size: Size of each chunk (default: 4MB)max_concurrency: Maximum parallel uploads (default: 10)r#type: File type hint (default: 1)
§Example
use baidu_netdisk_sdk::{BaiduNetDiskClient, upload::SimpleUploadOptions};
let client = BaiduNetDiskClient::builder().build()?;
client.load_token_from_env()?;
let options = SimpleUploadOptions::default()
.chunk_size(8 * 1024 * 1024) // 8MB chunks
.max_concurrency(20); // 20 parallel uploads
let response = client.upload()
.upload_file_with_options("large_video.mp4", "/remote/video.mp4", options)
.await?;
println!("Uploaded: {}", response.path);Examples found in repository?
6async fn main() -> Result<(), Box<dyn std::error::Error>> {
7 env_logger::init();
8
9 let client = BaiduNetDiskClient::builder().build()?;
10 info!("Client created successfully");
11
12 client.load_token_from_env()?;
13 info!("Token loaded successfully");
14
15 let args: Vec<String> = std::env::args().collect();
16
17 if args.len() < 3 {
18 println!(
19 "Usage: {} <local_file> <remote_path> [chunk_size] [concurrency]",
20 args[0]
21 );
22 println!("Example: {} test.mp4 /upload/video.mp4 8388608 20", args[0]);
23 println!(" - chunk_size: bytes per chunk (default: 4194304 = 4MB)");
24 println!(" - concurrency: parallel uploads (default: 10)");
25 return Ok(());
26 }
27
28 let local_file = &args[1];
29 let remote_path = &args[2];
30
31 let chunk_size: usize = args
32 .get(3)
33 .and_then(|s| s.parse().ok())
34 .unwrap_or(4 * 1024 * 1024);
35 let concurrency: usize = args.get(4).and_then(|s| s.parse().ok()).unwrap_or(10);
36
37 let options = SimpleUploadOptions::default()
38 .chunk_size(chunk_size)
39 .max_concurrency(concurrency);
40
41 println!("=== Baidu NetDisk File Upload (Custom Options) ===");
42 println!("Local file: {}", local_file);
43 println!("Remote path: {}", remote_path);
44 println!(
45 "Chunk size: {} bytes ({:.2} MB)",
46 chunk_size,
47 chunk_size as f64 / 1024.0 / 1024.0
48 );
49 println!("Concurrency: {}", concurrency);
50 println!();
51
52 let start_time = std::time::Instant::now();
53
54 let response = client
55 .upload()
56 .upload_file_with_options(local_file, remote_path, options)
57 .await?;
58
59 println!("File uploaded successfully!");
60 println!(" FS ID: {}", response.fs_id);
61 println!(" Path: {}", response.path);
62 println!(" Size: {} bytes", response.size);
63 println!(" Category: {}", response.category);
64 println!(" MD5: {}", response.md5.unwrap_or_default());
65 println!(" Upload time: {:?}", start_time.elapsed());
66
67 Ok(())
68}Sourcepub async fn upload_reader<R: Read + Seek>(
&self,
reader: &mut R,
file_size: u64,
remote_path: &str,
) -> NetDiskResult<CreateFileResponse>
pub async fn upload_reader<R: Read + Seek>( &self, reader: &mut R, file_size: u64, remote_path: &str, ) -> NetDiskResult<CreateFileResponse>
Upload from a Reader with seek support (streaming API)
This is a lower-level API that accepts any Read + Seek reader.
Useful for:
- Custom file wrapping (e.g., encrypted files)
- Upload from memory-mapped files
- Testing with custom readers
§Example
use baidu_netdisk_sdk::BaiduNetDiskClient;
use std::io::BufReader;
let client = BaiduNetDiskClient::builder().build()?;
client.load_token_from_env()?;
let file = std::fs::File::open("test.txt")?;
let metadata = file.metadata()?;
let file_size = metadata.len();
let reader = BufReader::new(file);
let mut reader = reader; // mutable for rewind
let response = client.upload()
.upload_reader(&mut reader, file_size, "/remote/test.txt")
.await?;
println!("Uploaded: {}", response.path);§Memory Usage
Memory is bounded by batch size (max_concurrency * 2 * chunk_size),
approximately 80MB by default, regardless of file size.
Examples found in repository?
6async fn main() -> Result<(), Box<dyn std::error::Error>> {
7 env_logger::init();
8
9 let client = BaiduNetDiskClient::builder().build()?;
10 info!("Client created successfully");
11
12 client.load_token_from_env()?;
13 info!("Token loaded successfully");
14
15 let args: Vec<String> = std::env::args().collect();
16
17 let local_file = if args.len() >= 2 {
18 &args[1]
19 } else {
20 println!("Usage: {} <local_file> [remote_path]", args[0]);
21 println!("Example: {} test.txt /upload/test.txt", args[0]);
22 return Ok(());
23 };
24
25 let remote_path = if args.len() >= 3 {
26 &args[2]
27 } else {
28 "/upload/test_reader.txt"
29 };
30
31 println!("=== Baidu NetDisk Reader Upload ===");
32 println!("Local file: {}", local_file);
33 println!("Remote path: {}", remote_path);
34 println!();
35
36 let file = std::fs::File::open(local_file)?;
37 let metadata = file.metadata()?;
38 let file_size = metadata.len();
39
40 println!("File size: {} bytes", file_size);
41
42 let mut reader = BufReader::new(file);
43
44 let start_time = std::time::Instant::now();
45
46 let response = client
47 .upload()
48 .upload_reader(&mut reader, file_size, remote_path)
49 .await?;
50
51 println!("File uploaded successfully!");
52 println!(" FS ID: {}", response.fs_id);
53 println!(" Server filename: {:?}", response.server_filename);
54 println!(" Path: {}", response.path);
55 println!(" Size: {} bytes", response.size);
56 println!(" Category: {}", response.category);
57 println!(" MD5: {}", response.md5.unwrap_or_default());
58 println!(" Upload time: {:?}", start_time.elapsed());
59
60 Ok(())
61}Sourcepub async fn upload_reader_with_options<R: Read + Seek>(
&self,
reader: &mut R,
file_size: u64,
remote_path: &str,
options: SimpleUploadOptions,
) -> NetDiskResult<CreateFileResponse>
pub async fn upload_reader_with_options<R: Read + Seek>( &self, reader: &mut R, file_size: u64, remote_path: &str, options: SimpleUploadOptions, ) -> NetDiskResult<CreateFileResponse>
Upload from a Reader with custom options
§Example
use baidu_netdisk_sdk::{BaiduNetDiskClient, upload::SimpleUploadOptions};
let client = BaiduNetDiskClient::builder().build()?;
client.load_token_from_env()?;
let options = SimpleUploadOptions::default()
.chunk_size(8 * 1024 * 1024)
.max_concurrency(20);
let file = std::fs::File::open("test.txt")?;
let metadata = file.metadata()?;
let file_size = metadata.len();
let mut reader = std::io::BufReader::new(file);
let response = client.upload()
.upload_reader_with_options(&mut reader, file_size, "/remote/test.txt", options)
.await?;
println!("Uploaded: {}", response.path);Sourcepub async fn upload_bytes(
&self,
data: &[u8],
remote_path: &str,
) -> NetDiskResult<CreateFileResponse>
pub async fn upload_bytes( &self, data: &[u8], remote_path: &str, ) -> NetDiskResult<CreateFileResponse>
Upload bytes from memory (simple API)
Use this method when you already have the data in memory.
For large data, consider using UploadClient::upload_file or UploadClient::upload_reader instead
to avoid loading the entire data into memory.
§Example
use baidu_netdisk_sdk::BaiduNetDiskClient;
let client = BaiduNetDiskClient::builder().build()?;
client.load_token_from_env()?;
let data = b"Hello, World!";
let response = client.upload()
.upload_bytes(data, "/remote/hello.txt")
.await?;
println!("Uploaded: {}", response.path);§Memory Note
The entire data slice will be held in memory during upload.
For large files, use UploadClient::upload_file which streams from disk.
Examples found in repository?
5async fn main() -> Result<(), Box<dyn std::error::Error>> {
6 env_logger::init();
7
8 let client = BaiduNetDiskClient::builder().build()?;
9 info!("Client created successfully");
10
11 client.load_token_from_env()?;
12 info!("Token loaded successfully");
13
14 let args: Vec<String> = std::env::args().collect();
15
16 let remote_path = if args.len() >= 2 {
17 &args[1]
18 } else {
19 "/upload/hello_bytes.txt"
20 };
21
22 println!("=== Baidu NetDisk Bytes Upload (Simple) ===");
23 println!("Remote path: {}", remote_path);
24 println!();
25
26 let test_data = b"Hello from upload_bytes! This is a simple byte array upload test.";
27 println!("Uploading {} bytes of data...", test_data.len());
28
29 let start_time = std::time::Instant::now();
30
31 let response = client.upload().upload_bytes(test_data, remote_path).await?;
32
33 println!("Bytes uploaded successfully!");
34 println!(" FS ID: {}", response.fs_id);
35 println!(" Server filename: {:?}", response.server_filename);
36 println!(" Path: {}", response.path);
37 println!(" Size: {} bytes", response.size);
38 println!(" Category: {}", response.category);
39 println!(" MD5: {}", response.md5.unwrap_or_default());
40 println!(" Upload time: {:?}", start_time.elapsed());
41
42 Ok(())
43}Sourcepub async fn upload_bytes_with_options(
&self,
data: &[u8],
remote_path: &str,
options: SimpleUploadOptions,
) -> NetDiskResult<CreateFileResponse>
pub async fn upload_bytes_with_options( &self, data: &[u8], remote_path: &str, options: SimpleUploadOptions, ) -> NetDiskResult<CreateFileResponse>
Upload bytes from memory with custom options
§Example
use baidu_netdisk_sdk::{BaiduNetDiskClient, upload::SimpleUploadOptions};
let client = BaiduNetDiskClient::builder().build()?;
client.load_token_from_env()?;
let options = SimpleUploadOptions::default()
.chunk_size(8 * 1024 * 1024)
.max_concurrency(20);
let data = b"Hello, World!";
let response = client.upload()
.upload_bytes_with_options(data, "/remote/hello.txt", options)
.await?;
println!("Uploaded: {}", response.path);Trait Implementations§
Source§impl Clone for UploadClient
impl Clone for UploadClient
Source§fn clone(&self) -> UploadClient
fn clone(&self) -> UploadClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more