1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
pub mod build;
pub mod write;
pub use build::build;
pub use write::write;
use std::path::{Path, PathBuf};
/// Information about a chunk for index file
#[derive(Debug, Clone)]
pub struct ChunkInfo {
/// Index of the chunk in the file
pub index: usize,
/// Hash of the chunk (hex string)
pub hash: String,
/// Size of the chunk in bytes
pub size: usize,
/// Start position in the original file
pub start: usize,
/// End position in the original file (exclusive)
pub end: usize,
}
/// 根据hash值计算chunk文件的存储路径
///
/// # 参数
/// - `storage_dir`: 存储目录
/// - `hash_hex`: chunk的hash值(16进制字符串)
///
/// # 返回
/// 返回chunk文件的完整路径
pub fn get_chunk_path(storage_dir: &Path, hash_hex: &str) -> PathBuf {
let first_slice = &hash_hex[0..2];
let second_slice = &hash_hex[2..4];
storage_dir
.join(first_slice)
.join(second_slice)
.join(hash_hex)
}
/// 根据hash字节数组计算chunk文件的存储路径
///
/// # 参数
/// - `storage_dir`: 存储目录
/// - `hash_bytes`: chunk的hash值(字节数组)
///
/// # 返回
/// 返回chunk文件的完整路径
pub fn get_chunk_path_from_bytes(storage_dir: &Path, hash_bytes: &[u8; 32]) -> PathBuf {
let hash_hex = hex::encode(hash_bytes);
get_chunk_path(storage_dir, &hash_hex)
}
/// 生成唯一的文件路径,如果文件已存在则添加数字后缀
///
/// # 参数
/// - `output_dir`: 输出目录
/// - `desired_filename`: 期望的文件名
///
/// # 返回
/// 返回唯一的文件路径
pub fn generate_unique_path(output_dir: &Path, desired_filename: &str) -> PathBuf {
let desired_path = output_dir.join(desired_filename);
let mut candidate = desired_path.clone();
let mut counter = 1;
while candidate.exists() {
let path_buf = PathBuf::from(desired_filename);
if let Some(stem) = path_buf.file_stem() {
if let Some(ext) = path_buf.extension() {
let ext_str = ext.to_string_lossy();
let new_name = if ext_str.is_empty() {
format!("{}_{}", stem.to_string_lossy(), counter)
} else {
format!("{}.{}_{}", stem.to_string_lossy(), ext_str, counter)
};
candidate = output_dir.join(new_name);
} else {
candidate = output_dir.join(format!("{}_{}", stem.to_string_lossy(), counter));
}
} else {
candidate = output_dir.join(format!("{}_{}", desired_filename, counter));
}
counter += 1;
}
candidate
}
|