1. 程式人生 > >List泛型自定義型別排序和大小比較C#版

List泛型自定義型別排序和大小比較C#版

想刪除一堆大小相同的檔案,於是想到用List泛型自定義型別排序和大小比較,準備先大小排序,再比較刪除同大小的

1、隨便來個自定義類

public class FileSort
    {
        long filesize;

        public long Filesize
        {
            get { return filesize; }
            set { filesize = value; }
        }

        string filepath;

        public string Filepath
        {
            get { return filepath; }
            set { filepath = value; }
        }
    }

2、List<FileSort> list= new List<FileSort>();

    把需要處理的檔案資訊填進list  //此處程式碼略

3、自定義排序

 private int CompareByFileSize(FileSort x, FileSort y)
        {
            int returnVal = y.Filesize.CompareTo(x.Filesize);
            return returnVal;
        }

        list.Sort(CompareByFileSize);


4、比較大小,刪除相同大小的

                int m = 0;
                while (m < list.Count - 1)
                {
                    if (list[m].Filesize == list[m + 1].Filesize)
                    {
                        new FileInfo(list[m + 1].Filepath).Delete();
                        list.RemoveAt(m + 1);
                    }
                    else
                    {
                        m++;
                    }
                }


 5、要是覺得大小相同還不放心的話那就再加個hash吧

我設定一個檔案大於16K的話用FileStream讀檔案開頭的16K,小於則全部讀進byte[] readBytes

int hash = Encoding.ASCII.GetString(readBytes).GetHashCode(); 比較的話先比大小,大小一樣加比hash

                int m = 0;
                while (m < list.Count - 1)
                {
                    if (list[m].Filesize == list[m + 1].Filesize)
                    {
                        if (list[m].Hash == list[m + 1].Hash)
                        {
                             new FileInfo(list[m + 1].Filepath).Delete();
                            list.RemoveAt(m + 1);
                        }
                        else
                        {
                            m++;
                        }
                    }
                    else
                    {
                        m++;
                    }
                }

完整程式碼

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Text;
using System.ComponentModel;

namespace TEST
{
    public partial class Form1 : Form
    {
        StringBuilder sb = new StringBuilder();

        public Form1()
        {
            InitializeComponent();
            textBox1.Text = "不顯示查詢速度更快適合大資料量檔案操作";
        }

        public void FindFileShow(object o)
        {
            FindParameter fp = (FindParameter)o;
            DirectoryInfo di = new DirectoryInfo(fp.Path);
            FileInfo[] fis = di.GetFiles(fp.Filename);
            DirectoryInfo[] dis = di.GetDirectories();

            foreach (FileInfo i in fis)
            {
                this.Invoke(new MethodInvoker(() => { sb.Append(i.FullName + "\r\n"); textBox1.Text = sb.ToString(); label3.Text = (int.Parse(label3.Text) + 1).ToString(); }));
            }

            foreach (DirectoryInfo i in dis)
            {
                try
                {
                    fp.Path = i.FullName;
                    FindFileShow(fp);
                }
                catch (Exception)
                {
                    //Undo
                }
            }
        }

        public void FindFileHide(object o)
        {
            FindParameter fp = (FindParameter)o;
            DirectoryInfo di = new DirectoryInfo(fp.Path);
            FileInfo[] fis = di.GetFiles(fp.Filename);
            DirectoryInfo[] dis = di.GetDirectories();

            foreach (FileInfo i in fis)
            {
                this.Invoke(new MethodInvoker(() => { sb.Append(i.FullName + "\r\n"); label3.Text = (int.Parse(label3.Text) + 1).ToString(); }));
            }

            foreach (DirectoryInfo i in dis)
            {
                try
                {
                    fp.Path = i.FullName;
                    FindFileHide(fp);
                }
                catch (Exception)
                {
                    //Undo
                }
            }
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            this.Width = 1024;
            this.Height = 768;
        }

        private void textBox2_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("需要手動輸入查詢路徑嗎(檔案量太大時手動輸入可減少不必要的開啟時間)?", "手動確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                //Undo
            }
            else
            {
                FolderBrowserDialog fbd = new FolderBrowserDialog();
                if (fbd.ShowDialog() == DialogResult.OK)
                    textBox2.Text = fbd.SelectedPath;
            }
        }

        private int CompareByFileSize(FileSort x, FileSort y)
        {
            int returnVal = y.Filesize.CompareTo(x.Filesize);
            return returnVal;
        }

        private int CompareByHash(FileSort x, FileSort y)
        {
            int returnVal = y.Hash.CompareTo(x.Hash);
            return returnVal;
        }

        private int CompareByFileName(FileSort x, FileSort y)
        {
            int returnVal = y.Filename.CompareTo(x.Filename);
            return returnVal;
        }

        private void 顯示目錄查詢ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sb = new StringBuilder();
            textBox1.Text = "";
            label3.Text = "0";
            FindParameter fp = new FindParameter();
            fp.Path = textBox2.Text;
            fp.Filename = textBox3.Text;
            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = false;
            worker.DoWork += (s, o) =>
            {
                FindFileShow(fp);
            };
            worker.RunWorkerCompleted += (s, o) =>
            {
                MessageBox.Show("查詢成功!");
            };
            worker.RunWorkerAsync();
        }

        private void 不顯示目錄查詢ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            sb = new StringBuilder();
            textBox1.Text = "不顯示查詢速度更快適合大資料量檔案操作";
            label3.Text = "0";
            FindParameter fp = new FindParameter();
            fp.Path = textBox2.Text;
            fp.Filename = textBox3.Text;
            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = false;
            worker.DoWork += (s, o) =>
            {
                FindFileHide(fp);
            };
            worker.RunWorkerCompleted += (s, o) =>
            {
                MessageBox.Show("查詢成功!");
            };
            worker.RunWorkerAsync();
        }

        private void 刪除所有找到ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("確定要刪除所有找到檔案嗎?", "刪除確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                BackgroundWorker worker = new BackgroundWorker();
                worker.WorkerReportsProgress = true;
                progressBar1.Visible = true;
                progressBar1.Value = 0;
                worker.DoWork += (s, o) =>
                {
                    string[] filepath = sb.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                    int k = 1;
                    foreach (string i in filepath)
                    {
                        try
                        {
                            FileInfo fi = new FileInfo(i);
                            fi.Delete();
                        }
                        catch (Exception)
                        {
                            //Undo
                        }
                        worker.ReportProgress((int)((float)k / (float)filepath.Length * 100), null);
                        k++;
                    }
                };
                worker.ProgressChanged += (s, o) =>
                {
                    progressBar1.Style = ProgressBarStyle.Continuous;
                    progressBar1.Value = o.ProgressPercentage;
                };
                worker.RunWorkerCompleted += (s, o) =>
                {
                    progressBar1.Visible = false;
                    MessageBox.Show("刪除成功!");
                };
                worker.RunWorkerAsync();
            }
        }

        private void 刪除大小重複ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("確定要刪除大小重複檔案嗎?", "刪除確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                BackgroundWorker worker = new BackgroundWorker();
                worker.WorkerReportsProgress = true;
                progressBar1.Visible = true;
                progressBar1.Value = 0;
                worker.DoWork += (s, o) =>
                {
                    string[] filepath = sb.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                    List<FileSort> list = new List<FileSort>();
                    int k = 1;
                    foreach (string i in filepath)
                    {
                        try
                        {
                            FileInfo fi = new FileInfo(i);
                            FileSort fs = new FileSort();
                            fs.Filesize = fi.Length;
                            fs.Filepath = i;
                            list.Add(fs);
                        }
                        catch (Exception)
                        {
                            //Undo
                        }
                        worker.ReportProgress((int)((float)k / (float)filepath.Length * 50), null);
                        k++;
                    }

                    list.Sort(CompareByFileSize);
                    int m = 0;
                    while (m < list.Count - 1)
                    {
                        if (list[m].Filesize == list[m + 1].Filesize)
                        {
                            new FileInfo(list[m + 1].Filepath).Delete();
                            list.RemoveAt(m + 1);
                        }
                        else
                        {
                            m++;
                            worker.ReportProgress((int)((float)m / (float)(list.Count - 1) * 50) + 50, null);
                        }
                    }
                };
                worker.ProgressChanged += (s, o) =>
                {
                    progressBar1.Style = ProgressBarStyle.Continuous;
                    progressBar1.Value = o.ProgressPercentage;
                };
                worker.RunWorkerCompleted += (s, o) =>
                {
                    progressBar1.Visible = false;
                    MessageBox.Show("刪除成功!");
                };
                worker.RunWorkerAsync();
            }
        }

        private void 一般精確刪除重複ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("確定要一般精確刪除重複檔案嗎?", "刪除確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                BackgroundWorker worker = new BackgroundWorker();
                worker.WorkerReportsProgress = true;
                progressBar1.Visible = true;
                progressBar1.Value = 0;
                worker.DoWork += (s, o) =>
                {
                    string[] filepath = sb.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                    int k = 1;
                    List<FileSort> list = new List<FileSort>();
                    foreach (string i in filepath)
                    {
                        try
                        {
                            FileInfo fi = new FileInfo(i);
                            FileSort fs = new FileSort();
                            fs.Filesize = fi.Length;
                            fs.Filepath = i;
                            FileStream file = fi.OpenRead();
                            byte[] read;
                            if (fi.Length >= 1024 * 16)
                            {
                                read = new byte[1024 * 16];
                                file.Seek(0, SeekOrigin.Begin);
                                file.Read(read, 0, 1024 * 16);
                                file.Close();
                            }
                            else
                            {
                                read = new byte[fi.Length];
                                file.Seek(0, SeekOrigin.Begin);
                                file.Read(read, 0, (int)fi.Length);
                                file.Close();
                            }
                            fs.Hash = Encoding.ASCII.GetString(read).GetHashCode();
                            list.Add(fs);
                        }
                        catch (Exception)
                        {
                            //Undo
                        }
                        worker.ReportProgress((int)((float)k / (float)filepath.Length * 50), null);
                        k++;
                    }
                    list.Sort(CompareByFileSize);
                    int m = 0;
                    while (m < list.Count - 1)
                    {
                        if (list[m].Filesize == list[m + 1].Filesize)
                        {
                            if (list[m].Hash == list[m + 1].Hash)
                            {
                                new FileInfo(list[m + 1].Filepath).Delete();
                                list.RemoveAt(m + 1);
                            }
                            else
                            {
                                m++;
                                worker.ReportProgress((int)((float)m / (float)(list.Count - 1) * 50) + 50, null);
                            }
                        }
                        else
                        {
                            m++;
                            worker.ReportProgress((int)((float)m / (float)(list.Count - 1) * 50) + 50, null);
                        }
                    }
                };
                worker.ProgressChanged += (s, o) =>
                {
                    progressBar1.Style = ProgressBarStyle.Continuous;
                    progressBar1.Value = o.ProgressPercentage;
                };
                worker.RunWorkerCompleted += (s, o) =>
                {
                    progressBar1.Visible = false;
                    MessageBox.Show("刪除成功!");
                };
                worker.RunWorkerAsync();
            }
        }

        private void 完全精確刪除重複ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("確定要完全精確刪除重複檔案嗎?", "刪除確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                BackgroundWorker worker = new BackgroundWorker();
                worker.WorkerReportsProgress = true;
                progressBar1.Visible = true;
                progressBar1.Value = 0;
                worker.DoWork += (s, o) =>
                {
                    string[] filepath = sb.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                    int k = 1;
                    List<FileSort> list = new List<FileSort>();
                    foreach (string i in filepath)
                    {
                        try
                        {
                            FileInfo fi = new FileInfo(i);
                            FileSort fs = new FileSort();
                            fs.Filesize = fi.Length;
                            fs.Filepath = i;
                            FileStream file = fi.OpenRead();
                            byte[] read = new byte[(int)fi.Length];
                            file.Seek(0, SeekOrigin.Begin);
                            file.Read(read, 0, (int)fi.Length);
                            file.Close();
                            fs.Hash = Encoding.ASCII.GetString(read).GetHashCode();
                            list.Add(fs);
                        }
                        catch (Exception)
                        {
                            //Undo
                        }
                        worker.ReportProgress((int)((float)k / (float)filepath.Length * 50), null);
                        k++;
                    }
                    list.Sort(CompareByFileSize);
                    int m = 0;
                    while (m < list.Count - 1)
                    {
                        if (list[m].Filesize == list[m + 1].Filesize)
                        {
                            if (list[m].Hash == list[m + 1].Hash)
                            {
                                new FileInfo(list[m + 1].Filepath).Delete();
                                list.RemoveAt(m + 1);
                            }
                            else
                            {
                                m++;
                                worker.ReportProgress((int)((float)m / (float)(list.Count - 1) * 50) + 50, null);
                            }
                        }
                        else
                        {
                            m++;
                            worker.ReportProgress((int)((float)m / (float)(list.Count - 1) * 50) + 50, null);
                        }
                    }
                };
                worker.ProgressChanged += (s, o) =>
                {
                    progressBar1.Style = ProgressBarStyle.Continuous;
                    progressBar1.Value = o.ProgressPercentage;
                };
                worker.RunWorkerCompleted += (s, o) =>
                {
                    progressBar1.Visible = false;
                    MessageBox.Show("刪除成功!");
                };
                worker.RunWorkerAsync();
            }
        }

        private void 刪除舊時間重複檔案ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("確定要刪除重複名稱舊時間檔案嗎?", "刪除確認", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                BackgroundWorker worker = new BackgroundWorker();
                worker.WorkerReportsProgress = true;
                progressBar1.Visible = true;
                progressBar1.Value = 0;
                worker.DoWork += (s, o) =>
                {
                    string[] filepath = sb.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                    int k = 1;
                    List<FileSort> list = new List<FileSort>();
                    foreach (string i in filepath)
                    {
                        try
                        {
                            FileInfo fi = new FileInfo(i);
                            FileSort fs = new FileSort();
                            fs.Filename = fi.Name;
                            fs.Filepath = i;
                            fs.Lasttime = fi.LastWriteTimeUtc;
                            list.Add(fs);
                        }
                        catch (Exception)
                        {
                            //Undo
                        }
                        worker.ReportProgress((int)((float)k / (float)filepath.Length * 50), null);
                        k++;
                    }
                    list.Sort(CompareByFileName);
                    int m = 0;
                    while (m < list.Count - 1)
                    {
                        if (list[m].Filename == list[m + 1].Filename)
                        {
                            if (list[m].Lasttime >= list[m + 1].Lasttime)
                            {
                                new FileInfo(list[m + 1].Filepath).Delete();
                                list.RemoveAt(m + 1);
                            }
                            else
                            {
                                new FileInfo(list[m].Filepath).Delete();
                                list.RemoveAt(m);
                            }
                        }
                        else
                        {
                            m++;
                            worker.ReportProgress((int)((float)m / (float)(list.Count - 1) * 50) + 50, null);
                        }
                    }
                };
                worker.ProgressChanged += (s, o) =>
                {
                    progressBar1.Style = ProgressBarStyle.Continuous;
                    progressBar1.Value = o.ProgressPercentage;
                };
                worker.RunWorkerCompleted += (s, o) =>
                {
                    progressBar1.Visible = false;
                    MessageBox.Show("刪除成功!");
                };
                worker.RunWorkerAsync();
            }
        }
    }

    public class FindParameter
    {
        string path;

        public string Path
        {
            get { return path; }
            set { path = value; }
        }
        string filename;

        public string Filename
        {
            get { return filename; }
            set { filename = value; }
        }
    }

    public class FileSort
    {
        long filesize;

        public long Filesize
        {
            get { return filesize; }
            set { filesize = value; }
        }

        string filepath;

        public string Filepath
        {
            get { return filepath; }
            set { filepath = value; }
        }

        int hash;

        public int Hash
        {
            get { return hash; }
            set { hash = value; }
        }

        string filename;

        public string Filename
        {
            get { return filename; }
            set { filename = value; }
        }

        DateTime lasttime;

        public DateTime Lasttime
        {
            get { return lasttime; }
            set { lasttime = value; }
        }
    }
}