NEWS

[C#] Tìm kiếm file trùng nhau trong cùng thư mục lập trình Winform

[C#] Tìm kiếm file trùng nhau trong cùng thư mục lập trình Winform
Đăng bởi: Thảo Meo - Lượt xem: 7483 14:52:48, 08/08/2019C#   In bài viết

Xin chào các bạn, bài viết hôm nay mình sẽ hướng dẫn các bạn cách tìm kiếm file trùng nhau trên cùng một thư mục Windows bằng ngôn ngữ lập trình C#.

[C#] Find Duplicate File in Directory Winform

Trong mỗi người chúng ta, thường hay sử dụng chép nhạc hay file ảnh hoặc một tập tin gì đó qua lại giữa các folder hoặc chung một folder.

Thường các bạn sẽ dễ tìm thấy, sau thời gian chúng ta sử dụng sẽ phát sinh nhiều file trùng giống nhau, nguyên nhân chính là do Copy.

Thay vì chúng ta tìm kiếm thủ công nó để xóa, thì chúng ta có thể viết một ứng dụng nhỏ để tìm file nào giống nhau, và liệt kê ra danh sách cho chúng ta xóa một cách dễ dàng.

Vậy làm thế nào để biết được file có trùng hay không?

Trong bài viết này, mình sẽ kiểm tra checksum file hash của từng file, nếu file nào có trùng mã hash, thì file đó là file trùng và mình liệt kê vào một group.

Các bạn có thể tìm hiểu checksum file ở bài viết trước qua link ở đây: Checksum file in C#

Dưới đây là giao diện demo ứng dụng tìm kiếm file trùng nhau C#:

duplicate_file_csharp_demo

Source code C# Check file trùng trên Winform:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


using Microsoft.VisualBasic.FileIO;

using System.IO;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace howto_find_duplicate_files
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

     
        private void Form1_Load(object sender, EventArgs e)
        {
            txtDirectory.Text = Properties.Settings.Default.Directory;
            splitContainer1.Panel2.BackColor = Color.White;
            picImage.SizeMode = PictureBoxSizeMode.Zoom;
            picImage.Dock = DockStyle.Fill;
            picImage.Visible = false;
            rchText.Dock = DockStyle.Fill;
            rchText.Visible = false;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.Directory = txtDirectory.Text;
            Properties.Settings.Default.Save();
        }
     
        private void btnBrowse_Click(object sender, EventArgs e)
        {
            fbdDirectory.SelectedPath = txtDirectory.Text;
            if (fbdDirectory.ShowDialog() == DialogResult.OK)
                txtDirectory.Text = fbdDirectory.SelectedPath;
        }

       
        private void btnSearch_Click(object sender, EventArgs e)
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();

            Cursor = Cursors.WaitCursor;
            trvFiles.Visible = false;
            trvFiles.Nodes.Clear();
            lblNumDuplicates.Text = "";
            Refresh();

            try
            {               
                var get_info =
                    from string filename in Directory.GetFiles(txtDirectory.Text)
                    select new
                    {
                        Name = filename,
                        Hash = BytesToString(GetHash(filename))
                    };
               
                var group_infos =
                    from info in get_info
                    group info by info.Hash into g
                    where g.Count() > 1
                    //orderby g.Key
                    select g;
                
                int num_groups = 0;
                int num_files = 0;
                foreach (var g in group_infos)
                {
                    num_groups++;
                    TreeNode hash_node = trvFiles.Nodes.Add(g.Key.ToString());
                    foreach (var info in g)
                    {
                        num_files++;
                        TreeNode file_node = new TreeNode(info.Name);
                        file_node.Tag = new FileInfo(info.Name);
                        hash_node.Nodes.Add(file_node);
                    }
                }
               
                lblNumDuplicates.Text =
                    (num_files - num_groups).ToString() +
                    " files trùng.";
               
                trvFiles.ExpandAll();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {               
                if (trvFiles.Nodes.Count > 0)
                    trvFiles.Nodes[0].EnsureVisible();
                trvFiles.Visible = true;

                Cursor = Cursors.Default;
            }

            watch.Stop();
            Console.WriteLine(watch.Elapsed.TotalSeconds.ToString("0.00") + " seconds");
        }
     
        private void trvFiles_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (Deleting) return;
         
            rchText.Visible = false;
            picImage.Visible = false;
            Refresh();

           
            if (e.Node.Level == 0) return;
         
            FileInfo file_info = e.Node.Tag as FileInfo;
            switch (file_info.Extension.ToLower())
            {
                case ".txt":  
                case ".html":
                case ".cs":
                case ".csproj":
                case ".resx":
                case ".xml":
                case ".xaml":
                case ".config":
                    rchText.Text = File.ReadAllText(file_info.FullName);
                    rchText.Visible = true;
                    break;

                case ".rtf":   
                    rchText.LoadFile(file_info.FullName);
                    rchText.Visible = true;
                    break;

                case ".jpg":   
                case ".jpeg":
                case ".gif":
                case ".png":
                case ".tiff":
                case ".bmp":
                    picImage.Image = LoadBitmapUnlocked(file_info.FullName);
                    picImage.Visible = true;
                    break;

                default:
                    rchText.Text = "Unknown file extension " + file_info.Extension;
                    rchText.Visible = true;
                    break;
            }
        }

       
        private void btnSelectDuplicates_Click(object sender, EventArgs e)
        {
            foreach (TreeNode hash_node in trvFiles.Nodes)
            {
                hash_node.Checked = false;
                hash_node.Nodes[0].Checked = false;
                for (int i = 1; i < hash_node.Nodes.Count; i++)
                    hash_node.Nodes[i].Checked = true;
            }
        }

        
        private bool Deleting = false;
        private void btnDeleteSelected_Click(object sender, EventArgs e)
        {
            Deleting = true;
            trvFiles.Visible = false;
            lblNumDuplicates.Text = "";
            picImage.Visible = false;
            picImage.Image = null;
            rchText.Visible = false;
            Cursor = Cursors.WaitCursor;
            Refresh();

            try
            {
                
                List<TreeNode> nodes_to_delete = new List<TreeNode>();
                foreach (TreeNode hash_node in trvFiles.Nodes)
                {
                    foreach (TreeNode file_node in hash_node.Nodes)
                    {                       
                        if (file_node.Checked) nodes_to_delete.Add(file_node);
                    }
                }
                
                foreach (TreeNode file_node in nodes_to_delete)
                {                    
                    FileInfo file_info = file_node.Tag as FileInfo;
                    
                    DeleteFile(file_info.FullName);                    
                    file_node.Remove();
                }
               
                nodes_to_delete = new List<TreeNode>();
                foreach (TreeNode hash_node in trvFiles.Nodes)
                {
                    if (hash_node.Nodes.Count == 0) nodes_to_delete.Add(hash_node);
                }
                
                foreach (TreeNode hash_node in nodes_to_delete)
                {
                    hash_node.Remove();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {               
                if (trvFiles.Nodes.Count > 0)
                    trvFiles.Nodes[0].EnsureVisible();
                trvFiles.Visible = true;

                Deleting = false;
                Cursor = Cursors.Default;
            }
        }
       
        public static void DeleteFile(string filename)
        {
            DeleteFile(filename, false, false);
        }
        public static void DeleteFile(string filename, bool confirm)
        {
            DeleteFile(filename, confirm, false);
        }
        public static void DeleteFile(string filename, bool confirm, bool delete_permanently)
        {
            UIOption ui_option = UIOption.OnlyErrorDialogs;
            if (confirm) ui_option = UIOption.AllDialogs;

            RecycleOption recycle_option =
                recycle_option = RecycleOption.SendToRecycleBin;
            if (delete_permanently)
                recycle_option = RecycleOption.DeletePermanently;

            try
            {
                FileSystem.DeleteFile(filename, ui_option, recycle_option);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error deleting file.\n" + ex.Message,
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
       
        private void trvFiles_AfterCheck(object sender, TreeViewEventArgs e)
        {           
            if (e.Node.Level == 0)
            {
                foreach (TreeNode file_node in e.Node.Nodes)
                {
                    file_node.Checked = e.Node.Checked;
                }
            }
        }
        
        private MD5 Md5 = MD5.Create();
       
        private byte[] GetHash(string filename)
        {
            using (FileStream stream = File.OpenRead(filename))
            {
                return Md5.ComputeHash(stream);
            }
        }
        
        private string BytesToString(byte[] bytes)
        {
            string result = "";
            foreach (byte b in bytes) result += b.ToString("x2");
            return result;
        }
      
        private Bitmap LoadBitmapUnlocked(string file_name)
        {
            using (Bitmap bm = new Bitmap(file_name))
            {
                return new Bitmap(bm);
            }
        }
    }
}

Thanks for watching!

 

DOWNLOAD SOURCE

 

 

THÔNG TIN TÁC GIẢ

BÀI VIẾT LIÊN QUAN

[C#] Tìm kiếm file trùng nhau trong cùng thư mục lập trình Winform
Đăng bởi: Thảo Meo - Lượt xem: 7483 14:52:48, 08/08/2019C#   In bài viết

CÁC BÀI CÙNG CHỦ ĐỀ

Đọc tiếp
.