rcmd_core/util/
filesys.rs

1use std::{io, fs};
2use std::path::{Path, PathBuf};
3use std::fs::{File};
4use std::io::{Seek, Write, Read};
5use zip::write::FileOptions;
6use walkdir::DirEntry;
7use crypto::md5::Md5;
8use crypto::digest::Digest;
9use zip::result::ZipError;
10use zip_extensions::*;
11
12///获取文件的md5值
13/// ## Example:
14/// ```
15/// use rcmd_core::util::filesys::file_md5;
16/// let ret: String = file_md5("c://a.txt");
17/// ```
18pub fn file_md5(path: &str) -> String{
19    let mut f = File::open(path).unwrap();
20    let mut buffer = Vec::new();
21    f.read_to_end(&mut buffer).unwrap();
22
23    let mut hasher = Md5::new();
24    hasher.input(&buffer);
25    return hasher.result_str();
26}
27
28
29///拷贝当前文件夹内所有文件到指定文件夹
30///##Exmample
31/// ```
32/// //todo
33/// //copy_dir_all()
34/// ```
35pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
36    fs::create_dir_all(&dst)?;
37    for entry in fs::read_dir(src)? {
38        let entry = entry?;
39        let ty = entry.file_type()?;
40        if ty.is_dir() {
41            copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
42        } else {
43            fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
44        }
45    }
46    Ok(())
47}
48
49
50///压缩指定路径的所有文件到zip
51///###Example:
52///```
53/// use rcmd_core::util::filesys::zip_dir;
54/// use rcmd_core::Ex::walkdir::WalkDir;
55///
56/// let zipfile = std::fs::File::create(target).unwrap();
57/// let dir  = WalkDir::new(src_dir);
58/// zip_dir(&mut dir.into_iter().filter_map(|e|e.ok()), src_dir.to_str().unwrap(), zipfile);
59///```
60///
61///
62pub fn zip_dir<T>(it: &mut dyn Iterator<Item=DirEntry>, prefix: &str, writer: T) -> zip::result::ZipResult<()>
63    where T: Write + Seek {
64    let mut zip = zip::ZipWriter::new(writer);
65    let options = FileOptions::default()
66        .compression_method(zip::CompressionMethod::Stored)//直接用了bzip2压缩方式,其它参看枚举
67        .unix_permissions(0o755);//unix系统权限
68
69    let mut buffer = Vec::new();
70    for entry in it {
71        let path = entry.path();
72        //zip压缩一个文件时,会把它的全路径当成文件名(在下面的解压函数中打印文件名可知)
73        //这里是去掉目录前缀
74        let name = path.strip_prefix(Path::new(prefix)).unwrap();
75        // Write file or directory explicitly
76        // Some unzip tools unzip files with directory paths correctly, some do not!
77        if path.is_file() {
78            zip.start_file_from_path(name, options)?;
79            let mut f = File::open(path)?;
80
81            f.read_to_end(&mut buffer)?;
82            zip.write_all(&*buffer)?;
83            buffer.clear();
84        } else if name.as_os_str().len() != 0 {//目录
85            // Only if not root! Avoids path spec / warning
86            // and mapname conversion failed error on unzip
87            zip.add_directory_from_path(name, options)?;
88        }
89    }
90    zip.finish()?;
91    Result::Ok(())
92}
93
94pub fn unzip_to_path(zip_f: &str, tar_p: &str) -> Result<(), ZipError>{
95    let zip_ar = zip::ZipArchive::new(File::open(zip_f).unwrap()).unwrap();
96    let out = Path::new(tar_p);
97    zip_extract(&Path::new(zip_f).to_path_buf(), &out.to_path_buf())
98}