xref: /DADK/dadk-user/src/utils/file.rs (revision 5129c63bfab60a54627def29dc1b53c722677e4e)
1 use std::{
2     fs::File,
3     path::Path,
4     process::{Command, Stdio},
5 };
6 
7 use reqwest::{blocking::ClientBuilder, Url};
8 
9 use super::stdio::StdioUtils;
10 
11 pub struct FileUtils;
12 
13 impl FileUtils {
14     ///从指定url下载文件到指定路径
15     pub fn download_file(url: &str, path: &Path) -> Result<(), Box<dyn std::error::Error>> {
16         let tempurl = Url::parse(url).expect("failed to parse the url");
17         let file_name = tempurl
18             .path_segments()
19             .expect("connot be base url")
20             .last()
21             .expect("failed to get the filename from the url");
22         let client = ClientBuilder::new()
23             .timeout(std::time::Duration::from_secs(10))
24             .build()?;
25         let mut response = client.get(url).send()?;
26         let mut file = File::create(path.join(file_name))?;
27         response.copy_to(&mut file)?;
28         Ok(())
29     }
30 
31     /// 把指定路径下所有文件和文件夹递归地移动到另一个文件中
32     pub fn move_files(src: &Path, dst: &Path) -> std::io::Result<()> {
33         for entry in src.read_dir()? {
34             let entry = entry?;
35             let path = entry.path();
36             let new_path = dst.join(path.file_name().unwrap());
37             if entry.file_type()?.is_dir() {
38                 std::fs::create_dir_all(&new_path)?;
39                 FileUtils::move_files(&path, &new_path)?;
40             } else {
41                 std::fs::rename(&path, &new_path)?;
42             }
43         }
44         Ok(())
45     }
46 
47     /// 递归地复制给定目录下所有文件到另一个文件夹中
48     pub fn copy_dir_all(src: &Path, dst: &Path) -> Result<(), String> {
49         let mut cmd = Command::new("cp");
50         cmd.arg("-r").arg("-f").arg("./").arg(dst);
51 
52         cmd.current_dir(src);
53 
54         // 创建子进程,执行命令
55         let proc: std::process::Child = cmd
56             .stderr(Stdio::piped())
57             .spawn()
58             .map_err(|e| e.to_string())?;
59         let output = proc.wait_with_output().map_err(|e| e.to_string())?;
60 
61         if !output.status.success() {
62             return Err(format!(
63                 "copy_dir_all failed, status: {:?},  stderr: {:?}",
64                 output.status,
65                 StdioUtils::tail_n_str(StdioUtils::stderr_to_lines(&output.stderr), 5)
66             ));
67         }
68         Ok(())
69     }
70 }
71