FileUtils.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. namespace MeloongCore;
  2. public static class FileUtils {
  3. #region 写入
  4. /// <summary>
  5. /// 写入文件。
  6. /// 如果文件或文件夹不存在,则会自动创建。若已存在,则会覆盖原文件。
  7. /// </summary>
  8. public static void Write(string filePath, string text, Encoding? encoding = null) {
  9. DirectoryUtils.Create(filePath, isFilePath: true);
  10. File.WriteAllText(filePath, text, encoding ?? new UTF8Encoding());
  11. }
  12. /// <summary>
  13. /// 写入文件。
  14. /// 如果文件或文件夹不存在,则会自动创建。若已存在,则会覆盖原文件。
  15. /// </summary>
  16. public static void Write(string filePath, byte[] content) {
  17. DirectoryUtils.Create(filePath, isFilePath: true);
  18. File.WriteAllBytes(filePath, content);
  19. }
  20. /// <summary>
  21. /// 将 <paramref name="stream" /> 写入文件。
  22. /// 会将流的位置主动重置到开头。
  23. /// 如果文件或文件夹不存在,则会自动创建。若已存在,则会覆盖原文件。
  24. /// </summary>
  25. public static void Write(string filePath, Stream stream) {
  26. DirectoryUtils.Create(filePath, isFilePath: true);
  27. using FileStream fileStream = new(filePath, FileMode.Create, FileAccess.Write);
  28. if (stream.CanSeek && stream.Position != 0) stream.Seek(0, SeekOrigin.Begin);
  29. stream.CopyTo(fileStream);
  30. }
  31. #endregion
  32. #region 短路径
  33. /// <summary>
  34. /// 若路径较长,则尽量将其转换为短路径。
  35. /// 若输入的是文件夹路径,不保证其结尾是否有 \ 。
  36. /// </summary>
  37. public static string ShortenPath(string fullName, bool keepFileName = false) {
  38. if (string.IsNullOrEmpty(fullName) || fullName.Length <= 200) return fullName;
  39. fullName = fullName.Replace('/', '\\');
  40. // 保留文件名
  41. string pathToKeep = "";
  42. string pathToShorten = fullName;
  43. if (fullName.EndsWithF(".jar", true)) keepFileName = true; // jar 文件的文件名需要保留原样,否则会导致 Forge 1.20.1 无法通过文件名识别模块名
  44. if (keepFileName && File.Exists(fullName)) {
  45. pathToKeep = Path.GetFileName(fullName);
  46. pathToShorten = Path.GetDirectoryName(fullName);
  47. }
  48. // 逐级向上寻找已存在的文件夹,将不存在的部分挪到 suffix,不再缩短
  49. while (!Directory.Exists(pathToShorten) && !File.Exists(pathToShorten)) { // 如果路径不存在
  50. string parentPath = Path.GetDirectoryName(pathToShorten);
  51. if (string.IsNullOrEmpty(parentPath) || parentPath == pathToShorten) return fullName; // 已经到达根目录,全都不存在,直接返回
  52. pathToKeep = Path.Combine(Path.GetFileName(pathToShorten), pathToKeep);
  53. pathToShorten = parentPath;
  54. }
  55. if (pathToShorten.Length <= 10) return fullName;
  56. // 缩短路径
  57. char[] buffer = new char[260];
  58. int result = GetShortPathNameW(pathToShorten, buffer, buffer.Length);
  59. if (result == 0) return fullName;
  60. string shortPath = new(buffer, 0, result);
  61. return Path.Combine(shortPath, pathToKeep);
  62. }
  63. [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
  64. private static extern int GetShortPathNameW(string lpszLongPath, [Out] char[] buffer, int cchBuffer);
  65. #endregion
  66. }