modify file tree
This commit is contained in:
@@ -10,7 +10,7 @@ use std::os::windows::process::CommandExt;
|
|||||||
// 存储全盘扫描后的结果
|
// 存储全盘扫描后的结果
|
||||||
pub struct DiskState {
|
pub struct DiskState {
|
||||||
pub dir_sizes: Mutex<HashMap<String, u64>>,
|
pub dir_sizes: Mutex<HashMap<String, u64>>,
|
||||||
pub file_info: Mutex<HashMap<String, (u64, u32)>>,
|
// pub file_info: Mutex<HashMap<String, (u64, u32)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Clone)]
|
#[derive(Serialize, Clone)]
|
||||||
@@ -101,16 +101,11 @@ pub async fn disable_hibernation() -> Result<String, String> {
|
|||||||
pub async fn run_full_scan(root_path: String, state: &DiskState) {
|
pub async fn run_full_scan(root_path: String, state: &DiskState) {
|
||||||
use jwalk::WalkDir;
|
use jwalk::WalkDir;
|
||||||
let mut dir_sizes = HashMap::new();
|
let mut dir_sizes = HashMap::new();
|
||||||
let mut file_info = HashMap::new();
|
|
||||||
let root = Path::new(&root_path);
|
let root = Path::new(&root_path);
|
||||||
|
|
||||||
for entry in WalkDir::new(root).skip_hidden(false).into_iter().filter_map(|e| e.ok()) {
|
for entry in WalkDir::new(root).skip_hidden(false).into_iter().filter_map(|e| e.ok()) {
|
||||||
if entry.file_type.is_file() {
|
if entry.file_type.is_file() {
|
||||||
let size = entry.metadata().map(|m| m.len()).unwrap_or(0);
|
let size = entry.metadata().map(|m| m.len()).unwrap_or(0);
|
||||||
if let Some(parent) = entry.parent_path().to_str() {
|
|
||||||
let info = file_info.entry(parent.to_string()).or_insert((0, 0));
|
|
||||||
info.0 += size; info.1 += 1;
|
|
||||||
}
|
|
||||||
let mut current_path = entry.parent_path().to_path_buf();
|
let mut current_path = entry.parent_path().to_path_buf();
|
||||||
while current_path.starts_with(root) {
|
while current_path.starts_with(root) {
|
||||||
let path_str = current_path.to_string_lossy().to_string();
|
let path_str = current_path.to_string_lossy().to_string();
|
||||||
@@ -121,42 +116,41 @@ pub async fn run_full_scan(root_path: String, state: &DiskState) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut state_dirs = state.dir_sizes.lock().unwrap();
|
let mut state_dirs = state.dir_sizes.lock().unwrap();
|
||||||
let mut state_files = state.file_info.lock().unwrap();
|
*state_dirs = dir_sizes;
|
||||||
*state_dirs = dir_sizes; *state_files = file_info;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_children(parent_path: String, state: &DiskState) -> Vec<FileTreeNode> {
|
pub fn get_children(parent_path: String, state: &DiskState) -> Vec<FileTreeNode> {
|
||||||
let dir_sizes = state.dir_sizes.lock().unwrap();
|
let dir_sizes = state.dir_sizes.lock().unwrap();
|
||||||
let file_info = state.file_info.lock().unwrap();
|
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
let parent_size = *dir_sizes.get(&parent_path).unwrap_or(&1);
|
let parent_size = *dir_sizes.get(&parent_path).unwrap_or(&1);
|
||||||
|
|
||||||
if let Ok(entries) = fs::read_dir(Path::new(&parent_path)) {
|
if let Ok(entries) = fs::read_dir(Path::new(&parent_path)) {
|
||||||
for entry in entries.filter_map(|e| e.ok()) {
|
for entry in entries.filter_map(|e| e.ok()) {
|
||||||
if entry.file_type().map(|t| t.is_dir()).unwrap_or(false) {
|
let path = entry.path();
|
||||||
let path_str = entry.path().to_string_lossy().to_string();
|
let path_str = path.to_string_lossy().to_string();
|
||||||
if let Some(&size) = dir_sizes.get(&path_str) {
|
let is_dir = path.is_dir();
|
||||||
results.push(FileTreeNode {
|
let name = entry.file_name().to_string_lossy().to_string();
|
||||||
name: entry.file_name().to_string_lossy().to_string(),
|
|
||||||
path: path_str, is_dir: true, size, size_str: format_size(size),
|
let size = if is_dir {
|
||||||
percent: (size as f64 / parent_size as f64 * 100.0) as f32,
|
*dir_sizes.get(&path_str).unwrap_or(&0)
|
||||||
file_count: 0, has_children: true,
|
} else {
|
||||||
});
|
entry.metadata().map(|m| m.len()).unwrap_or(0)
|
||||||
}
|
};
|
||||||
|
|
||||||
|
if size > 0 || !is_dir {
|
||||||
|
results.push(FileTreeNode {
|
||||||
|
name,
|
||||||
|
path: path_str,
|
||||||
|
is_dir,
|
||||||
|
size,
|
||||||
|
size_str: format_size(size),
|
||||||
|
percent: (size as f64 / parent_size as f64 * 100.0) as f32,
|
||||||
|
file_count: 0,
|
||||||
|
has_children: is_dir,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(&(size, count)) = file_info.get(&parent_path) {
|
|
||||||
if count > 0 {
|
|
||||||
results.push(FileTreeNode {
|
|
||||||
name: format!("[{} 个文件]", count),
|
|
||||||
path: format!("{}\\__files__", parent_path),
|
|
||||||
is_dir: false, size, size_str: format_size(size),
|
|
||||||
percent: (size as f64 / parent_size as f64 * 100.0) as f32,
|
|
||||||
file_count: count, has_children: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
results.sort_by(|a, b| b.size.cmp(&a.size));
|
results.sort_by(|a, b| b.size.cmp(&a.size));
|
||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ pub fn run() {
|
|||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
.manage(cleaner::DiskState {
|
.manage(cleaner::DiskState {
|
||||||
dir_sizes: Mutex::new(HashMap::new()),
|
dir_sizes: Mutex::new(HashMap::new()),
|
||||||
file_info: Mutex::new(HashMap::new()),
|
// file_info: Mutex::new(HashMap::new()),
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
start_fast_scan,
|
start_fast_scan,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
{
|
{
|
||||||
"title": "Windows 清理工具",
|
"title": "Windows 清理工具",
|
||||||
"width": 1400,
|
"width": 1400,
|
||||||
"height": 900
|
"height": 950
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
|||||||
Reference in New Issue
Block a user