use std::fs::{self, File, OpenOptions};
use std::io::{self, Read, Write};
use std::path::{Path, PathBuf};
use chksum_md5 as md5;
use lazy_static::lazy_static;
use std::sync::Mutex;
use std::collections::HashMap;
lazy_static! {
pub static ref FILE_LIST: Mutex<Vec<String>> = Mutex::new(Vec::new());
pub static ref FILE_INFO_LIST: Mutex<HashMap<String, String>> = Mutex::new(HashMap::new());
}
fn exists(path: &str) -> bool {
fs::metadata(path).is_ok()
}
pub mod e9571_file_lib {
use super::*;
pub fn list_file(myfolder: &str) -> Result<HashMap<String, String>, io::Error> {
let mut out_put = HashMap::new();
let entries = fs::read_dir(myfolder)?;
for entry in entries {
let file = entry?;
let path = file.path();
let path_str = path.to_str().unwrap_or("").to_string();
let parent_str = myfolder.to_string();
out_put.insert(path_str, parent_str);
}
Ok(out_put)
}
pub fn visit(path: &str) {
let mut file_info_list = FILE_INFO_LIST.lock().unwrap();
file_info_list.insert(path.to_string(), path.to_string());
}
pub fn file_md5(path: &str) -> String {
let file = match File::open(path) {
Ok(file) => file,
Err(e) => {
println!("Open: {}", e);
return String::new();
}
};
match md5::chksum(file) {
Ok(digest) => digest.to_hex_uppercase(),
Err(e) => {
println!("Checksum: {}", e);
String::new()
}
}
}
pub fn file_rename(source_file: &str, target_file: &str) {
match fs::rename(source_file, target_file) {
Ok(_) => println!("file rename OK!"),
Err(e) => println!("file rename Error: {}", e),
}
}
pub fn get_filelist(path: &str) -> Vec<String> {
let mut path_tmp = Vec::new();
if let Err(e) = walk_dir_files(path, &mut path_tmp) {
println!("filepath.Walk() returned: {}", e);
}
path_tmp
}
fn walk_dir_files(path: &str, paths: &mut Vec<String>) -> io::Result<()> {
for entry in fs::read_dir(path)? {
let file = entry?;
let file_path = file.path();
if file.file_type()?.is_dir() {
walk_dir_files(file_path.to_str().unwrap_or(""), paths)?;
} else {
paths.push(file_path.to_str().unwrap_or("").to_string());
}
}
Ok(())
}
pub fn walk_dir(dir_pth: &str, suffix: &str) -> Result<Vec<String>, io::Error> {
let mut files = Vec::new();
let suffix_upper = suffix.to_uppercase();
walk_dir_recursive(dir_pth, &suffix_upper, &mut files)?;
Ok(files)
}
fn walk_dir_recursive(dir_pth: &str, suffix: &str, files: &mut Vec<String>) -> io::Result<()> {
for entry in fs::read_dir(dir_pth)? {
let file = entry?;
let path = file.path();
if file.file_type()?.is_dir() {
walk_dir_recursive(path.to_str().unwrap_or(""), suffix, files)?;
} else if path.file_name()
.and_then(|name| name.to_str())
.map(|name| name.to_uppercase().ends_with(suffix))
.unwrap_or(false) {
files.push(path.to_str().unwrap_or("").to_string());
}
}
Ok(())
}
pub fn get_files(folder: &str) {
if let Err(e) = get_files_recursive(folder) {
println!("read dir fail: {}", e);
}
}
fn get_files_recursive(folder: &str) -> io::Result<()> {
let entries = fs::read_dir(folder)?;
let mut file_list = FILE_LIST.lock().unwrap();
for entry in entries {
let file = entry?;
let path = file.path();
let path_str = path.to_str().unwrap_or("").to_string();
if file.file_type()?.is_dir() {
get_files_recursive(&path_str)?;
} else {
file_list.push(path_str);
}
}
Ok(())
}
pub fn get_all_file(pathname: &str, mut s: Vec<String>) -> Result<Vec<String>, io::Error> {
let entries = fs::read_dir(pathname)?;
for entry in entries {
let file = entry?;
if !file.file_type()?.is_dir() {
let full_name = format!("{}/{}", pathname, file.file_name().to_str().unwrap_or(""));
s.push(full_name);
}
}
Ok(s)
}
pub fn get_dir_list(dirpath: &str) -> Result<Vec<String>, io::Error> {
let mut dir_list = Vec::new();
walk_dir_dirs(dirpath, &mut dir_list)?;
Ok(dir_list)
}
fn walk_dir_dirs(path: &str, dirs: &mut Vec<String>) -> io::Result<()> {
for entry in fs::read_dir(path)? {
let file = entry?;
if file.file_type()?.is_dir() {
let path_str = file.path().to_str().unwrap_or("").to_string();
dirs.push(path_str.clone());
walk_dir_dirs(&path_str, dirs)?;
}
}
Ok(())
}
pub fn copy_file(src_name: &str, dst_name: &str) -> io::Result<(i64, io::Error)> {
let mut src = match File::open(src_name) {
Ok(file) => file,
Err(e) => return Ok((0, e)),
};
let mut dst = match OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(dst_name)
{
Ok(file) => file,
Err(e) => return Ok((0, e)),
};
match io::copy(&mut src, &mut dst) {
Ok(written) => Ok((written as i64, io::Error::new(io::ErrorKind::Other, "No error"))),
Err(e) => Ok((0, e)),
}
}
pub fn copy_file1(src: &str, dst: &str) -> io::Result<()> {
let mut src_file = File::open(src)?;
let mut dst_file = File::create(dst)?;
io::copy(&mut src_file, &mut dst_file)?;
dst_file.sync_all()?;
Ok(())
}
pub fn copy_dir(src: &str, dst: &str) -> io::Result<()> {
let entries = fs::read_dir(src)?;
for entry in entries {
let file = entry?;
let src_path = file.path();
let dst_path = Path::new(dst).join(file.file_name());
if file.file_type()?.is_dir() {
fs::create_dir_all(&dst_path)?;
copy_dir(src_path.to_str().unwrap_or(""), dst_path.to_str().unwrap_or(""))?;
} else {
copy_file1(src_path.to_str().unwrap_or(""), dst_path.to_str().unwrap_or(""))?;
}
}
Ok(())
}
pub fn check_file_is_exist(filename: &str) -> bool {
fs::metadata(filename).is_ok()
}
pub fn is_dir(name: &str) -> bool {
fs::metadata(name)
.map(|metadata| metadata.is_dir())
.unwrap_or(false)
}
pub fn is_file(path: &str) -> bool {
!is_dir(path)
}
pub fn create_new_file(file_name: &str) -> Result<String, io::Error> {
if check_file_is_exist(file_name) {
return Ok(file_name.to_string());
}
fs::create_dir(file_name)?;
Ok(file_name.to_string())
}
pub fn delete_files_in_dir(dir: &str) -> io::Result<()> {
for entry in fs::read_dir(dir)? {
let file = entry?;
if !file.file_type()?.is_dir() {
let path = file.path();
fs::remove_file(&path).map_err(|e| {
io::Error::new(
io::ErrorKind::Other,
format!("删除文件 {} 时出错: {}", path.display(), e),
)
})?;
println!("已删除文件: {}", path.display());
}
}
Ok(())
}
}