xCommonLib/utils/
file_utils.rs

1use std::collections::{LinkedList, VecDeque};
2
3use std::future::Future;
4use std::io::ErrorKind;
5use std::io::{self, Read};
6use std::path::{Path, PathBuf};
7use std::pin::Pin;
8use tokio::fs;
9use tokio::fs::File;
10use tokio::io::{AsyncReadExt, AsyncWriteExt};
11
12#[allow(dead_code)]
13pub async fn is_file_exist(file_path: &str) -> bool {
14    match fs::metadata(file_path).await {
15        Ok(metadata) => metadata.is_file(),
16        Err(_) => false,
17    }
18}
19
20#[allow(dead_code)]
21pub async fn is_dir_exist(dir_path: &str) -> bool {
22    match fs::metadata(dir_path).await {
23        Ok(metadata) => metadata.is_dir(),
24        Err(_) => false,
25    }
26}
27
28/**
29 * 递归创建目录
30 */
31#[allow(dead_code)]
32pub async fn create_dir(dir_path: &str) -> bool {
33 
34    match fs::create_dir_all(dir_path).await {
35        Ok(_) => true,
36        Err(_) => false,
37    }
38}
39
40
41
42
43
44#[allow(dead_code)]
45pub fn get_file_path_dir(file_path: &str) -> Option<String> {
46    if let Some(parent) = Path::new(file_path).parent() {
47        if let Some(dir) = parent.to_str() {
48            Some(dir.to_owned())
49        } else {
50            None
51        }
52    } else {
53        None
54    }
55}
56
57#[allow(dead_code)]
58pub fn get_absoule_path(file_path: &str) -> Option<String> {
59    let relative_path = Path::new(file_path);
60
61    if relative_path.is_relative() {
62        let current_dir = std::env::current_dir().unwrap();
63        let full_path = current_dir.join(relative_path).canonicalize().unwrap();
64
65        let mut path_buf = PathBuf::new();
66
67        for component in full_path.components() {
68            if let Some(str_component) = component.as_os_str().to_str() {
69                path_buf.push(str_component);
70            }
71        }
72        let full_path = path_buf.to_string_lossy().into_owned();
73
74        Some(full_path.replace("\\\\?\\", ""))
75    } else {
76        Some(file_path.to_string())
77    }
78}
79
80#[allow(dead_code)]
81pub async fn create_file(file_path: &str) -> bool {
82    if is_file_exist(file_path).await {
83        return true;
84    }
85    let dir_path = get_file_path_dir(file_path);
86    if dir_path.is_none() {
87        return false;
88    }
89    let dir_path = dir_path.expect("获取文件夹路径失败!");
90    if !create_dir(&dir_path).await {
91        return false;
92    }
93    match File::create(file_path).await {
94        Ok(_) => true,
95        Err(_) => false,
96    }
97}
98
99#[allow(dead_code)]
100pub fn create_dir_sync(dir_path: &str) -> bool {
101  std::fs::create_dir_all(dir_path).unwrap();
102  true
103}
104
105
106
107#[allow(dead_code)]
108pub fn create_file_path_sync(file_path: &str) -> bool {
109
110    let dir_path = get_file_path_dir(file_path);
111    if dir_path.is_none() {
112        return false;
113    }
114    let dir_path = dir_path.unwrap();
115
116    if Path::new(&dir_path).exists() {
117      return true;
118    }
119    return create_dir_sync(&dir_path);
120}
121
122#[allow(dead_code)]
123pub async fn write_content_to_file(file_path: &str, content: &str) -> std::io::Result<()> {
124    fs::write(file_path, content).await
125}
126
127#[allow(dead_code)]
128pub async fn read_file_as_string(file_path: &str) -> std::io::Result<String> {
129    fs::read_to_string(file_path).await
130}
131
132#[allow(dead_code)]
133pub async fn get_file_list(dir_path: &str) -> std::io::Result<LinkedList<String>> {
134    let mut file_list = LinkedList::new();
135    let mut entries = fs::read_dir(dir_path).await?;
136    while let Some(entry) = entries.next_entry().await? {
137        let file_name = entry.file_name();
138        let file_name = file_name.to_string_lossy().to_string();
139        file_list.push_back(file_name);
140    }
141    Ok(file_list)
142}
143
144#[allow(dead_code)]
145pub async fn get_file_list_recursively(
146    dir_path: &str,
147    is_add_path: bool,
148) -> std::io::Result<LinkedList<String>> {
149    let mut dirs_to_explore = VecDeque::new();
150    let mut file_list = LinkedList::new();
151    let base_path = PathBuf::from(dir_path);
152    dirs_to_explore.push_back(base_path.clone());
153    while let Some(current_dir) = dirs_to_explore.pop_front() {
154        let mut dir_entries = fs::read_dir(current_dir).await?;
155        while let Some(entry) = dir_entries.next_entry().await? {
156            let path = entry.path();
157            if path.is_dir() {
158                dirs_to_explore.push_back(path);
159            } else {
160                if is_add_path {
161                    if let Ok(stripped_path) = path.strip_prefix(&base_path) {
162                        file_list.push_back(stripped_path.display().to_string());
163                    }
164                } else {
165                    let file_name = entry.file_name();
166                    let file_name = file_name.to_string_lossy().to_string();
167                    file_list.push_back(file_name);
168                }
169            }
170        }
171    }
172    Ok(file_list)
173}
174
175#[allow(dead_code)]
176pub async fn copy_file(source_path: &str, destination_path: &str) -> std::io::Result<()> {
177    // 打开源文件和目标文件
178    let mut source_file = File::open(source_path).await?;
179    if !create_file(destination_path).await {
180        // "创建目标文件失败!"
181        return Err(io::Error::new(ErrorKind::Other, "创建目标文件失败!"));
182    }
183    let mut destination_file = File::create(destination_path).await?;
184    // 从源文件读取数据并写入目标文件
185    let mut buffer = vec![0; 4096];
186    loop {
187        let bytes_read = source_file.read(&mut buffer).await?;
188        if bytes_read == 0 {
189            // 已完成拷贝
190            break;
191        }
192        destination_file.write_all(&buffer[..bytes_read]).await?;
193    }
194    Ok(())
195}
196
197#[allow(dead_code)]
198pub fn get_file_name_from_path(file_path: &str) -> Option<String> {
199    let path = Path::new(file_path);
200    // 使用file_name方法获取文件名
201    if let Some(file_name) = path.file_name() {
202        if let Some(file_name_str) = file_name.to_str() {
203            return Some(String::from(file_name_str));
204        }
205    }
206    None
207}
208
209#[allow(dead_code)]
210pub async fn remove_all_dir(dir_path: &str) -> std::io::Result<()> {
211    if !is_dir_exist(dir_path).await {
212        return Ok(());
213    }
214    fs::remove_dir_all(dir_path).await?;
215    Ok(())
216}
217
218#[allow(dead_code)]
219pub fn get_md5(file_path: &str) -> std::io::Result<String> {
220    let file = std::fs::File::open(file_path)?;
221    let mut reader = std::io::BufReader::new(file);
222    let mut context = md5::Context::new();
223    let mut buffer = vec![0u8; 4 * 1024 * 1024];
224    loop {
225        let bytes_read = reader.read(&mut buffer)?;
226        if bytes_read == 0 {
227            break;
228        }
229        context.consume(&buffer[..bytes_read]);
230    }
231
232    let digest = context.compute();
233    Ok(format!("{:x}", digest))
234}