namespace dy.net.utils { public class DouyinFileUtils { /// /// 将字节数转换为GB(采用二进制换算:1GB = 1024^3 Byte) /// /// 字节数(需使用long类型避免大数值溢出) /// 保留的小数位数 /// 转换后的GB值 public static string ConvertBytesToGb(long bytes, int decimalPlaces = 2) { // 1GB = 1024 * 1024 * 1024 = 1073741824 Byte double gb = (double)bytes / 1073741824; // 四舍五入保留指定小数位数 return Math.Round(gb, decimalPlaces).ToString("F2"); } /// /// 获取宿主机所有本地固定磁盘的总空间(GB) /// /// 总空间字符串(如 "1408.35 GB"),失败时返回错误信息 public static string GetHostTotalDiskSpaceGB() { try { // 1. 获取所有驱动器 DriveInfo[] allDrives = DriveInfo.GetDrives(); // 2. 筛选:仅保留“就绪的本地固定磁盘”(DriveType.Fixed) var fixedDrives = allDrives.Where(drive => drive.IsReady && drive.DriveType == DriveType.Fixed ).ToList(); if (!fixedDrives.Any()) { return "未找到可用的本地固定磁盘"; } // 3. 累加所有固定磁盘的总空间(字节) long totalBytes = fixedDrives.Sum(drive => drive.TotalSize); // 4. 转换为GB并保留2位小数 return ConvertBytesToGb(totalBytes); } catch (UnauthorizedAccessException) { return "权限不足,无法访问部分磁盘"; } catch (Exception ex) { return $"获取宿主机总磁盘空间失败:{ex.Message}"; } } /// /// 极简版:计算多个文件的总大小(字节) /// /// 文件路径列表 /// 总字节数 public static long GetTotalFileSize(List filePaths) { long totalSize = 0; foreach (var path in filePaths) { // 仅判断文件是否存在,存在则累加大小 if (File.Exists(path)) { totalSize += new FileInfo(path).Length; } } return totalSize; } /// /// 检查指定文件夹是否有读取权限 /// /// 文件夹路径 /// 有读权限返回true,否则返回false public static bool HasDirectoryReadPermission(string directoryPath) { if (string.IsNullOrWhiteSpace(directoryPath)) return false; try { // 首先检查文件夹是否存在 if (!Directory.Exists(directoryPath)) return false; // 尝试枚举文件夹内容(核心验证读权限) // EnumerateFileSystemEntries 会触发实际的读权限检查 var entries = Directory.EnumerateFileSystemEntries(directoryPath); return true; } catch (UnauthorizedAccessException) { // 明确捕获无权限异常 return false; } catch (Exception ex) { // 其他异常(如路径无效、文件夹被占用等),视为无有效读权限 Console.WriteLine($"检查读权限时发生非权限异常: {ex.Message}"); return false; } } /// /// 检查指定文件夹是否有写入权限 /// /// 文件夹路径 /// 有写权限返回true,否则返回false public static bool HasDirectoryWritePermission(string directoryPath) { if (string.IsNullOrWhiteSpace(directoryPath)) return false; try { // 检查文件夹是否存在 if (!Directory.Exists(directoryPath)) return false; // 核心验证:在文件夹内创建临时文件(最直接的写权限验证) string tempFileName = $"temp_perm_check_{Guid.NewGuid()}.tmp"; string tempFilePath = Path.Combine(directoryPath, tempFileName); // 尝试创建临时文件 using (FileStream fs = File.Create(tempFilePath, 1, FileOptions.DeleteOnClose)) { // FileOptions.DeleteOnClose 确保即使程序异常退出,临时文件也会被删除 return true; } } catch (UnauthorizedAccessException) { return false; } catch (Exception ex) { Console.WriteLine($"检查写权限时发生非权限异常: {ex.Message}"); return false; } } /// /// 检查指定文件夹是否同时有读写权限 /// /// 文件夹路径 /// 同时有读写权限返回true,否则返回false public static bool HasDirectoryReadWritePermission(string directoryPath) { return HasDirectoryReadPermission(directoryPath) && HasDirectoryWritePermission(directoryPath); } /// /// 通过文件头魔数(前几个字节)识别真实文件类型 /// public static string GetFileExtensionByMagicNumber(Stream stream) { // 读取前16个字节(足够识别常见格式) byte[] magicBytes = new byte[16]; int readBytes = stream.Read(magicBytes, 0, magicBytes.Length); //stream.Position = 0; // 读完重置指针 if (readBytes < 4) return ""; // 字节数不足,兜底 // 魔数匹配规则(核心:区分MP4视频和M4A音频) // MP4/M4A 基础魔数:0x00 0x00 0x00 ?? 0x66 0x74 0x79 0x70 (ftyp) if (magicBytes[4] == 0x66 && magicBytes[5] == 0x74 && magicBytes[6] == 0x79 && magicBytes[7] == 0x70) { // 读取ftyp后的字符,区分MP4/M4A if (readBytes >= 12) { // MP4 特征:ftypmp42 / ftypisom / ftypmp41 string ftyp = System.Text.Encoding.ASCII.GetString(magicBytes, 8, 4); if (ftyp == "mp42" || ftyp == "isom" || ftyp == "mp41") { // 进一步判断是否包含视频轨道(简化版:M4A只有音频,MP4可能含视频) // 这里做简化区分:如果是纯音频则为m4a,否则为mp4 // (进阶版可解析MP4盒子,新手先按此规则) return "m4a"; // 你原链接的真实类型 // 若要严格区分视频MP4,可扩展:return "mp4"; } // M4A 特征:ftypM4A / ftypM4B / ftypM4P else if (ftyp == "M4A " || ftyp == "M4B " || ftyp == "M4P ") { return "m4a"; } } // 兜底:MP4/M4A统一先按Content-Type辅助,无则按mp4 return "mp4"; } // MP3 魔数:0xFF 0xFB 或 0x49 0x44 0x33 (ID3) else if ((magicBytes[0] == 0xFF && magicBytes[1] == 0xFB) || (magicBytes[0] == 0x49 && magicBytes[1] == 0x44 && magicBytes[2] == 0x33)) { return "mp3"; } // 其他常见格式(可扩展) else if (magicBytes[0] == 0xFF && magicBytes[1] == 0xD8) // JPG { return "jpg"; } else if (magicBytes[0] == 0x89 && magicBytes[1] == 0x50 && magicBytes[2] == 0x4E && magicBytes[3] == 0x47) // PNG { return "png"; } else { return ""; // 未知格式 } } } }