音樂文件自動整理工具

開篇先交代一下背景, 因爲本人喜歡在網上下載一些無損音樂放到本地聽,時間一長,導致本地存放音樂的文件夾裏的文件很多,看上去很雜亂,而一首一首歌去手動創建目錄又很複雜,所以今天休息的時候閒來無事,想到是不是可以做一個小工具,根據音樂文件的歌手和專輯名去自動創建目錄,把文件移動到創建好的目錄。

 

說做就做,第一步,確定需求。這裏其實很簡單,就是我輸入一個目錄,這個工具就會把該目錄下的音樂文件自動移動到對應的目錄,目錄規則爲 根目錄/歌手/專輯。確定了需求,接下來就是步驟:

  1. 遍歷根目錄下的所有文件;
  2. 篩選其中的音樂文件(有時下載的資源包括封面圖);
  3. 找出音樂文件的歌手和專輯名,並拼裝好新的目錄;
  4. 將當前音樂移動到指定目錄

下面放一下代碼,因爲本人用的是Windows系統,爲了省事,這次就用了C#開發(主要是WinForm用着順手),如果大家有更好的實現方式或者更棒的算法,歡迎提出~

目錄結構(其實挺簡單的,Logic層完全可以省略的)

界面(也很簡單,不會做美工啥的,自己用的,實現功能爲主吧)

按鈕部分代碼(這裏沒什麼主要邏輯,還是調用MainLogic爲主):

        private void btnStart_Click(object sender, EventArgs e)
        {
            string rootPath = this.tbRootPath.Text.Trim();
            MainLogic mainLogic = new MainLogic();
            if (mainLogic.isPathExist(rootPath))
            {
                try
                {
                    List<string> listFile = new List<string>();
                    DirectoryInfo directory = new DirectoryInfo(rootPath);
                    mainLogic.findFile(listFile, directory);
                    int num = 0;
                    foreach(string fileName in listFile)
                    {
                        if (mainLogic.isMusicFile(fileName))
                        {
                            string targetPath = rootPath;
                            string artist = mainLogic.getArtist(fileName);
                            string album = mainLogic.getAlbum(fileName);
                            if (!string.IsNullOrEmpty(artist) && !mainLogic.isAllQuestionMark(artist))
                            {
                                targetPath += "\\" + artist;
                            }
                            if (!string.IsNullOrEmpty(album) && !mainLogic.isAllQuestionMark(album))
                            {
                                targetPath += "\\" + album;
                            }
                            mainLogic.moveFile(fileName, targetPath);
                            num++;
                        }
                    }
                    showSuccessMessage("移動完成,本次處理文件" + num + "個");
                }
                catch (Exception ex)
                {
                    showErrorMessage(ex.Message);
                }
            }
            else
            {
                showErrorMessage("輸入的路徑不存在,請確認後操作");
            }
        }

遍歷目錄(這裏還是使用遞歸,只記錄文件,沒有記錄目錄,代碼部分引用自網友,感謝網友的無私分享~)

        public void findFile(List<string> listFiles, DirectoryInfo directoryInfo)
        {
            FileInfo[] fileInfos = directoryInfo.GetFiles();
            for (int i=0; i< fileInfos.Length; i++)
            {
                listFiles.Add(fileInfos[i].FullName);
            }
            DirectoryInfo[] directoryInfos = directoryInfo.GetDirectories();
            for (int i=0; i < directoryInfos.Length; i++)
            {
                findFile(listFiles, directoryInfos[i]);
            }
        }

判斷格式,因爲有時會下載出封面等其他信息,我自己最後是隻保留的音樂文件,所以這裏沒有管,如果大家有需求可以根據需要更改代碼~

        /// <summary>
        /// 判斷文件是否爲音樂文件
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public bool isMusicFile(string fileName)
        {
            string extension = Path.GetExtension(fileName);
            string targetExtension = ".mp3;.flac;.wma;.wav";
            if (targetExtension.IndexOf(extension) != -1)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

獲取歌手和專輯信息(文件的其他信息也可以使用這個方法獲取,可自行研究)

        /// <summary>
        /// 獲取歌手名
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public string getArtist(string fileName)
        {
            try
            {
                Shell32.Shell shell = new Shell();
                Folder dir = shell.NameSpace(System.IO.Path.GetDirectoryName(fileName));
                FolderItem item = dir.ParseName(System.IO.Path.GetFileName(fileName));
                string artist = dir.GetDetailsOf(item, 20);
                return artist;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 獲取專輯名
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public string getAlbum(string fileName)
        {
            try
            {
                Shell32.Shell shell = new Shell();
                Folder dir = shell.NameSpace(System.IO.Path.GetDirectoryName(fileName));
                FolderItem item = dir.ParseName(System.IO.Path.GetFileName(fileName));
                string album = dir.GetDetailsOf(item, 14);
                return album;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

移動文件:

        /// <summary>
        /// 移動文件
        /// </summary>
        /// <param name="sourcefileName"></param>
        /// <param name="targetDir"></param>
        public void moveFile(string sourcefileName, string targetDir)
        {
            try
            {
                if (!Directory.Exists(targetDir))
                {
                    Directory.CreateDirectory(targetDir);
                }
                if (!File.Exists(sourcefileName))
                {
                    throw new Exception("文件【" + sourcefileName + "】不存在,請檢查");
                }
                int index = sourcefileName.LastIndexOf("\\");
                string fileName = sourcefileName.Substring(index);
                string targetDestination = targetDir + fileName;
                if (!File.Exists(targetDestination))
                {
                    File.Move(sourcefileName, targetDestination);
                    //File.Delete(sourcefileName);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

後期發現一個問題,有些文件因爲資源問題,專輯名和歌手都是問號,這裏如果沒有發現的話,就會造成有帶問號的文件夾,還得自己處理,這裏的辦法是對這類文件不做處理,不拼接目錄名,具體代碼在上面界面的部分,下面爲判斷是否全部爲問號的代碼:

        /// <summary>
        /// 校驗信息是否全爲問號(有些歌曲文件會出現這種問題,可交由人工判斷,或完成填寫後使用)
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        public bool isAllQuestionMark(string info)
        {
            bool result = true;
            for (int i=0; i<info.Length; i++)
            {
                if (info[i] != '?')
                {
                    result = false;
                    break;
                }
            }
            return result;
        }

好了,至此就是這個小工具截至目前的主要代碼,詳細代碼可以在這裏看到:https://github.com/RazrZhang/MusicFilesHandler

小工具初版下載:

鏈接:https://pan.baidu.com/s/1T1pTYJn2JLaHmuLr1U-R8g
提取碼:rr87
運行效果大概是下面的樣子

整理前
軟件界面
整理完成

 

整理後

 

 

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

寫在最後:這個工具完成後比我預想的要簡單一些,本來以爲不同格式的文件要分開處理,但是後來發覺不需要,添加一個引用直接就完事了~這個工具運用System.IO這個庫比較多,自己之前用這個類庫用的也不是很多, 這次就當是做了一個練習吧,也想過用Java做,畢竟自己主攻方向是Java,但是自己GUI學的不咋地,而且又不如WinForm直接拖過來用就完事了,所以暫且就用C#吧,能達到目的就好,語言只是一種手段,不需要太多的糾結。當然這個工具也僅僅是實現了簡單功能,能把大部分音樂進行比較好的分類,有些多歌手的,做的還不是很好,所以後期還會繼續改進,有其他更好想法的朋友可以提出想法,我也會適當參考的~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章