improve scanning speed
This commit is contained in:
2 files changed
+61
-48
No files matched your search
+45
-39
@@ -1,6 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sysinfo::Disks;
|
||||
use tauri::{WebviewUrl, WebviewWindowBuilder};
|
||||
use tauri::{Emitter, WebviewUrl, WebviewWindowBuilder};
|
||||
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
#[cfg(target_os = "macos")]
|
||||
@@ -53,7 +53,7 @@ async fn get_file_info_from_dirs(
|
||||
app: tauri::AppHandle,
|
||||
path: String,
|
||||
min_ratio: String,
|
||||
) -> Result<DirScanResult, String> {
|
||||
) -> Result<(), String> {
|
||||
let cmd = app
|
||||
.shell()
|
||||
.sidecar("pdu")
|
||||
@@ -70,59 +70,65 @@ async fn get_file_info_from_dirs(
|
||||
let output = cmd.output().await.map_err(|e| e.to_string())?;
|
||||
|
||||
if !output.status.success() {
|
||||
return Err(format!(
|
||||
"pdu failed: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
));
|
||||
return Err(String::from_utf8_lossy(&output.stderr).to_string());
|
||||
}
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
let json: serde_json::Value =
|
||||
serde_json::from_str(&stdout).map_err(|e| format!("JSON parse failed: {}", e))?;
|
||||
let json: serde_json::Value = serde_json::from_str(&stdout).map_err(|e| e.to_string())?;
|
||||
|
||||
let mut items = Vec::new();
|
||||
if let Some(tree) = json.get("tree") {
|
||||
extract_files(tree, "", &mut items);
|
||||
let mut batch: Vec<FileInfo> = Vec::new();
|
||||
|
||||
stream_extract(tree, "", &mut batch, &app);
|
||||
}
|
||||
|
||||
let total_size = items.iter().map(|i| i.size).sum();
|
||||
|
||||
Ok(DirScanResult {
|
||||
items,
|
||||
total_size,
|
||||
error: None,
|
||||
})
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn extract_files(node: &serde_json::Value, parent_path: &str, items: &mut Vec<FileInfo>) {
|
||||
if let Some(name) = node.get("name").and_then(|v| v.as_str()) {
|
||||
let size = node.get("size").and_then(|v| v.as_u64()).unwrap_or(0);
|
||||
let children = node.get("children").and_then(|v| v.as_array());
|
||||
fn stream_extract(
|
||||
node: &serde_json::Value,
|
||||
parent_path: &str,
|
||||
batch: &mut Vec<FileInfo>,
|
||||
app: &tauri::AppHandle,
|
||||
) {
|
||||
let name = match node.get("name").and_then(|v| v.as_str()) {
|
||||
Some(n) => n,
|
||||
None => return,
|
||||
};
|
||||
|
||||
let is_dir = children.as_ref().map(|c| !c.is_empty()).unwrap_or(false);
|
||||
let size = node.get("size").and_then(|v| v.as_u64()).unwrap_or(0);
|
||||
let children = node.get("children").and_then(|v| v.as_array());
|
||||
|
||||
let path = if parent_path.is_empty() {
|
||||
name.to_string()
|
||||
} else {
|
||||
format!("{}/{}", parent_path, name)
|
||||
};
|
||||
let path = if parent_path.is_empty() {
|
||||
name.to_string()
|
||||
} else {
|
||||
format!("{}/{}", parent_path, name)
|
||||
};
|
||||
|
||||
items.push(FileInfo {
|
||||
name: name.to_string(),
|
||||
path: path.clone(),
|
||||
size,
|
||||
is_dir,
|
||||
});
|
||||
let is_dir = children.is_some();
|
||||
|
||||
if let Some(children_array) = children {
|
||||
if !children_array.is_empty() {
|
||||
for child in children_array {
|
||||
extract_files(child, &path, items);
|
||||
}
|
||||
}
|
||||
batch.push(FileInfo {
|
||||
name: name.to_string(),
|
||||
path: path.clone(),
|
||||
size,
|
||||
is_dir,
|
||||
});
|
||||
|
||||
if batch.len() >= 200 {
|
||||
let _ = app.emit("scan-batch", batch.clone());
|
||||
batch.clear();
|
||||
}
|
||||
|
||||
if let Some(children) = children {
|
||||
for child in children {
|
||||
stream_extract(child, &path, batch, app);
|
||||
}
|
||||
}
|
||||
|
||||
if parent_path.is_empty() && !batch.is_empty() {
|
||||
let _ = app.emit("scan-batch", batch.clone());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
|
||||
Reference in new issue
Block a user