朋友下了N多影片
記不住資料夾下都有啥了…
問批處理怎麼匯出資料夾下所有檔名及影片時長…
批處理匯出檔名好弄,獲取影片時長真沒用過…
想到 .net 控制檯程式 AOT 釋出,不和批處理差不多效果…
新建個控制檯專案選下使用AOT
首先要獲取檔案的時長,我們需要用下 TagLibSharp
Install-Package TagLibSharp
然後是遍歷資料夾,讓萬能的 chatgpt 寫一個:
/// <summary> /// 列出指定目錄及其子目錄中的檔案,限制遞迴深度。 /// </summary> /// <param name="path">當前目錄路徑</param> /// <param name="writer">StreamWriter 物件,用於寫入檔案</param> /// <param name="currentDepth">當前遞迴深度</param> static void ListFilesAndDirectories(string path, StreamWriter writer, int currentDepth) { // 最大遞迴深度設定為3 const int maxDepth = 3; // 如果當前深度超過最大深度,則返回 if (currentDepth > maxDepth) { return; } try { // 獲取當前目錄下的所有檔案 string[] files = Directory.GetFiles(path); foreach (string file in files) { if (file != outputFilePath && file != ownFilePath) { FileInfo fileInfo = new FileInfo(file); string fileInfoText = $"{fileInfo.Name}, {fileInfo.DirectoryName}\\, {ConvertBytesToReadableSize(fileInfo.Length)} "; // 判斷檔案型別並獲取時長(如果為音影片檔案) if (IsMediaFile(fileInfo.Extension)) { TimeSpan duration = GetMediaDuration(file); fileInfoText += $",{duration.ToString(@"hh\:mm\:ss")}"; } else { fileInfoText += $","; } // 寫入檔案資訊到文字檔案 Console.WriteLine($"檔名: {fileInfo.Name}, 大小: {ConvertBytesToReadableSize(fileInfo.Length)} 位元組"); writer.WriteLine(fileInfoText); } } // 獲取當前目錄下的所有子目錄 string[] directories = Directory.GetDirectories(path); foreach (string directory in directories) { // 遞迴呼叫以列出子目錄中的檔案,並增加遞迴深度 ListFilesAndDirectories(directory, writer, currentDepth + 1); } } catch (UnauthorizedAccessException ex) { // 處理無許可權訪問的異常 Console.WriteLine($"無法訪問目錄 {path}: {ex.Message}"); writer.WriteLine($"無法訪問目錄 {path}: {ex.Message}"); } catch (Exception ex) { // 處理其他異常 Console.WriteLine($"處理目錄 {path} 時出錯: {ex.Message}"); writer.WriteLine($"處理目錄 {path} 時出錯: {ex.Message}"); } }
我們根據字尾名來判斷下是否為音影片檔案:
/// <summary> /// 判斷檔案是否為音影片檔案 /// </summary> /// <param name="extension">副檔名</param> /// <returns>是否為音影片檔案</returns> static bool IsMediaFile(string extension) { string[] mediaExtensions = { ".mp3", ".wav", ".wma", ".m4a", ".mp4", ".avi", ".mkv", ".webm", ".mov" }; return Array.Exists(mediaExtensions, e => e.Equals(extension, StringComparison.OrdinalIgnoreCase)); }
如果是音影片檔案,返回時長:
/// <summary> /// 獲取音影片檔案的時長 /// </summary> /// <param name="filePath">音影片檔案路徑</param> /// <returns>時長</returns> static TimeSpan GetMediaDuration(string filePath) { try { // 使用 TagLib 獲取音影片檔案時長 var file = TagLib.File.Create(filePath); return file.Properties.Duration; } catch (Exception ex) { Console.WriteLine($"無法獲取檔案 {filePath} 的時長: {ex.Message}"); return TimeSpan.Zero; } }
最後格式化檔案大小,好看一些:
/// <summary> /// 將位元組轉換為可讀的檔案大小格式(如 KB, MB, GB 等)。 /// </summary> /// <param name="bytes">檔案大小(以位元組為單位)</param> /// <returns>可讀的檔案大小格式</returns> static string ConvertBytesToReadableSize(long bytes) { if (bytes < 0) { throw new ArgumentException("位元組數不能為負數。", nameof(bytes)); } // 定義檔案大小單位及其縮寫 string[] sizeUnits = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; int unitIndex = 0; double size = bytes; // 不斷除以 1024,直到找到合適的單位 while (size >= 1024 && unitIndex < sizeUnits.Length - 1) { size /= 1024; unitIndex++; } // 返回帶有單位的檔案大小,保留兩位小數 return $"{size:0.00} {sizeUnits[unitIndex]}"; }
最後填充下main函式,我們建立一個csv用於寫入資料
static void Main(string[] args) { DateTime d1=DateTime.Now; // 獲取當前目錄 string currentDirectory = Directory.GetCurrentDirectory(); ownFilePath = Process.GetCurrentProcess().MainModule.FileName; string filrName = $"FileList{d1.ToString("yyyyMMddHHmmss")}.csv"; // 定義輸出檔案路徑 outputFilePath = Path.Combine(currentDirectory, filrName); // 建立或覆蓋輸出檔案 using (StreamWriter writer = new StreamWriter(outputFilePath, false, System.Text.Encoding.UTF8)) { writer.WriteLine("檔名,路徑,大小,時長"); Console.WriteLine("檔名,路徑,大小,時長"); // 遞迴列出當前目錄及最多3層子目錄的檔案 ListFilesAndDirectories(currentDirectory, writer, 0); } Console.WriteLine("遍歷完畢,按回車退出!"); Console.ReadLine(); }
因為我們使用了第三方的包,在AOT釋出前需要處理下,給專案新增個 rd.xml 檔案,把我們的第三方包整合進去,檔案內容如下:
<Directives> <Application> <Assembly Name="TagLibSharp" Dynamic="Required All"> </Assembly> </Application> </Directives>
然後修改專案檔案,增加 rd.xml
最後就是AOT釋出了
目前vs還不支援直接AOT釋出(https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/aot/native-aot-tutorial?view=aspnetcore-8.0&tabs=visual-studio)
需要自己手打下命令
到 \bin\Release\net8.0\win-x64\publish 下就能看到釋出的檔案了
執行下看看效果:
生成的csv檔案: