diff --git a/czkawka_core/src/zeroed.rs b/czkawka_core/src/zeroed.rs index aca8a30..1989747 100644 --- a/czkawka_core/src/zeroed.rs +++ b/czkawka_core/src/zeroed.rs @@ -11,6 +11,7 @@ use crate::common_items::ExcludedItems; use crate::common_messages::Messages; use crate::common_traits::*; use crossbeam_channel::Receiver; +use rayon::prelude::*; #[derive(Eq, PartialEq, Clone, Debug)] pub enum DeleteMethod { @@ -54,6 +55,7 @@ pub struct ZeroedFiles { delete_method: DeleteMethod, stopped_search: bool, minimal_file_size: u64, + files_to_check: Vec, } impl ZeroedFiles { @@ -69,6 +71,7 @@ impl ZeroedFiles { delete_method: DeleteMethod::None, stopped_search: false, minimal_file_size: 1024, + files_to_check: Vec::with_capacity(1024), } } @@ -78,6 +81,10 @@ impl ZeroedFiles { self.stopped_search = true; return; } + if !self.check_for_zeroed_files(stop_receiver) { + self.stopped_search = true; + return; + } self.delete_files(); self.debug_print(); } @@ -210,49 +217,6 @@ impl ZeroedFiles { continue 'dir; } - let mut file_handler: File = match File::open(¤t_file_name) { - Ok(t) => t, - Err(_) => { - continue 'dir; - } - }; - - let mut first_search: bool = true; - let mut n; - loop { - if first_search { - let mut buffer = [0u8; 64]; - n = match file_handler.read(&mut buffer) { - Ok(t) => t, - Err(_) => { - continue 'dir; - } - }; - for i in buffer[0..n].iter() { - if *i != 0 { - continue 'dir; // Not zeroed file - } - } - first_search = false; - } else { - let mut buffer = [0u8; 1024 * 32]; - n = match file_handler.read(&mut buffer) { - Ok(t) => t, - Err(_) => { - continue 'dir; - } - }; - for i in buffer[0..n].iter() { - if *i != 0 { - continue 'dir; // Not zeroed file - } - } - } - if n == 0 { - break; - } - } - // Creating new file entry let fe: FileEntry = FileEntry { path: current_file_name.clone(), @@ -273,7 +237,7 @@ impl ZeroedFiles { }; // Adding files to Vector - self.zeroed_files.push(fe); + self.files_to_check.push(fe); self.information.number_of_checked_files += 1; } else { @@ -282,12 +246,78 @@ impl ZeroedFiles { } } } - self.information.number_of_zeroed_files = self.zeroed_files.len(); Common::print_time(start_time, SystemTime::now(), "check_files".to_string()); true } + /// Check files for files which have 0 + fn check_for_zeroed_files(&mut self, stop_receiver: Option<&Receiver<()>>) -> bool { + let start_time: SystemTime = SystemTime::now(); + + self.zeroed_files = self + .files_to_check + .par_iter() + .map(|file_entry| { + if stop_receiver.is_some() && stop_receiver.unwrap().try_recv().is_ok() { + // This will not break + return None; + } + + let file_entry = file_entry.clone(); + let mut n; + let mut file_handler: File = match File::open(&file_entry.path) { + Ok(t) => t, + Err(_) => { + return Some(None); + } + }; + + // First search + let mut buffer = [0u8; 64]; + n = match file_handler.read(&mut buffer) { + Ok(t) => t, + Err(_) => { + return Some(None); + } + }; + for i in buffer[0..n].iter() { + if *i != 0 { + return Some(None); + } + } + // Second search + loop { + let mut buffer = [0u8; 1024 * 32]; + n = match file_handler.read(&mut buffer) { + Ok(t) => t, + Err(_) => { + return Some(None); + } + }; + for i in buffer[0..n].iter() { + if *i != 0 { + return Some(None); + } + } + if n == 0 { + break; + } + } + + Some(Some(file_entry)) + }) + .while_some() + .filter(|file_entry| file_entry.is_some()) + .map(|file_entry| file_entry.unwrap()) + .collect::>(); + + self.information.number_of_zeroed_files = self.zeroed_files.len(); + + Common::print_time(start_time, SystemTime::now(), "search for zeroed_files".to_string()); + true + } + /// Function to delete files, from filed Vector fn delete_files(&mut self) { let start_time: SystemTime = SystemTime::now(); diff --git a/czkawka_gui/src/connect_button_search.rs b/czkawka_gui/src/connect_button_search.rs index 7060075..c0fc4a4 100644 --- a/czkawka_gui/src/connect_button_search.rs +++ b/czkawka_gui/src/connect_button_search.rs @@ -54,6 +54,7 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { let scrolled_window_same_music_finder = gui_data.scrolled_window_same_music_finder.clone(); let scrolled_window_similar_images_finder = gui_data.scrolled_window_similar_images_finder.clone(); let scrolled_window_zeroed_files_finder = gui_data.scrolled_window_zeroed_files_finder.clone(); + let text_view_errors = gui_data.text_view_errors.clone(); buttons_search_clone.connect_clicked(move |_| { let included_directories = get_string_from_list_store(&scrolled_window_included_directories); @@ -72,6 +73,7 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { match notebook_main_children_names.get(notebook_main.get_current_page().unwrap() as usize).unwrap().as_str() { "notebook_main_duplicate_finder_label" => { get_list_store(&scrolled_window_duplicate_finder).clear(); + text_view_errors.get_buffer().unwrap().set_text(""); let check_method; if radio_button_duplicates_name.get_active() { @@ -108,6 +110,8 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { } "scrolled_window_main_empty_folder_finder" => { get_list_store(&scrolled_window_main_empty_folder_finder).clear(); + text_view_errors.get_buffer().unwrap().set_text(""); + let sender = sender.clone(); let receiver_stop = stop_receiver.clone(); @@ -123,6 +127,8 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { } "scrolled_window_main_empty_files_finder" => { get_list_store(&scrolled_window_main_empty_files_finder).clear(); + text_view_errors.get_buffer().unwrap().set_text(""); + let sender = sender.clone(); let receiver_stop = stop_receiver.clone(); @@ -141,6 +147,8 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { } "scrolled_window_main_temporary_files_finder" => { get_list_store(&scrolled_window_main_temporary_files_finder).clear(); + text_view_errors.get_buffer().unwrap().set_text(""); + let sender = sender.clone(); let receiver_stop = stop_receiver.clone(); @@ -158,6 +166,8 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { } "notebook_big_main_file_finder" => { get_list_store(&scrolled_window_big_files_finder).clear(); + text_view_errors.get_buffer().unwrap().set_text(""); + let numbers_of_files_to_check = match entry_big_files_number.get_text().as_str().parse::() { Ok(t) => t, Err(_) => 50, // By default @@ -182,6 +192,8 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { "notebook_main_similar_images_finder_label" => { get_list_store(&scrolled_window_similar_images_finder).clear(); + text_view_errors.get_buffer().unwrap().set_text(""); + let sender = sender.clone(); let receiver_stop = stop_receiver.clone(); @@ -219,6 +231,8 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { } "notebook_main_zeroed_files_finder" => { get_list_store(&scrolled_window_zeroed_files_finder).clear(); + text_view_errors.get_buffer().unwrap().set_text(""); + let sender = sender.clone(); let receiver_stop = stop_receiver.clone(); @@ -237,6 +251,8 @@ pub fn connect_button_search(gui_data: &GuiData, sender: Sender) { } "notebook_main_same_music_finder" => { get_list_store(&scrolled_window_same_music_finder).clear(); + text_view_errors.get_buffer().unwrap().set_text(""); + let minimal_file_size = match entry_same_music_minimal_size.get_text().as_str().parse::() { Ok(t) => t, Err(_) => 1024, // By default diff --git a/czkawka_gui/src/startup_configuration.rs b/czkawka_gui/src/startup_configuration.rs index d05dae5..58a4169 100644 --- a/czkawka_gui/src/startup_configuration.rs +++ b/czkawka_gui/src/startup_configuration.rs @@ -265,7 +265,7 @@ pub fn startup_configuration(gui_data: &GuiData) { // Set Excluded Items { if cfg!(target_family = "unix") { - entry_excluded_items.set_text("*/.git/*,*/node_modules/*,*/lost+found/*"); + entry_excluded_items.set_text("*/.git/*,*/node_modules/*,*/lost+found/*,*/Trash/*"); } if cfg!(target_family = "windows") { entry_excluded_items.set_text("*/.git/*,*/node_modules/*,*/lost+found/*,*:/windows/*");