ASP.NET 8 AOT 遍历文件夹获取文件名称及时长
朋友下了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文件:
作者:sun8134
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。