FileExt.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using System.IO;
  2. using System.Security.Cryptography;
  3. using System.Text;
  4. using System.Threading.Tasks;
  5. namespace Masuit.Tools.Files
  6. {
  7. /// <summary>
  8. /// 大文件操作扩展类
  9. /// </summary>
  10. public static class FileExt
  11. {
  12. /// <summary>
  13. /// 以文件流的形式复制大文件
  14. /// </summary>
  15. /// <param name="fs">源</param>
  16. /// <param name="dest">目标地址</param>
  17. /// <param name="bufferSize">缓冲区大小,默认8MB</param>
  18. public static void CopyToFile(this Stream fs, string dest, int bufferSize = 1024 * 8 * 1024)
  19. {
  20. using var fsWrite = new FileStream(dest, FileMode.OpenOrCreate, FileAccess.ReadWrite);
  21. byte[] buf = new byte[bufferSize];
  22. int len;
  23. while ((len = fs.Read(buf, 0, buf.Length)) != 0)
  24. {
  25. fsWrite.Write(buf, 0, len);
  26. }
  27. }
  28. /// <summary>
  29. /// 以文件流的形式复制大文件(异步方式)
  30. /// </summary>
  31. /// <param name="fs">源</param>
  32. /// <param name="dest">目标地址</param>
  33. /// <param name="bufferSize">缓冲区大小,默认8MB</param>
  34. public static async Task CopyToFileAsync(this Stream fs, string dest, int bufferSize = 1024 * 1024 * 8)
  35. {
  36. using var fsWrite = new FileStream(dest, FileMode.OpenOrCreate, FileAccess.ReadWrite);
  37. byte[] buf = new byte[bufferSize];
  38. int len;
  39. while ((len = await fs.ReadAsync(buf, 0, buf.Length)) != 0)
  40. {
  41. await fsWrite.WriteAsync(buf, 0, len);
  42. }
  43. }
  44. /// <summary>
  45. /// 将内存流转储成文件
  46. /// </summary>
  47. /// <param name="ms"></param>
  48. /// <param name="filename"></param>
  49. public static void SaveFile(this Stream ms, string filename)
  50. {
  51. using var fs = new FileStream(filename, FileMode.Create, FileAccess.Write);
  52. byte[] buffer = ms.ToArray(); // 转化为byte格式存储
  53. fs.Write(buffer, 0, buffer.Length);
  54. fs.Flush();
  55. }
  56. /// <summary>
  57. /// 计算文件的 MD5 值
  58. /// </summary>
  59. /// <param name="fs">源文件流</param>
  60. /// <returns>MD5 值16进制字符串</returns>
  61. public static string GetFileMD5(this FileStream fs) => HashFile(fs, "md5");
  62. /// <summary>
  63. /// 计算文件的 sha1 值
  64. /// </summary>
  65. /// <param name="fs">源文件流</param>
  66. /// <returns>sha1 值16进制字符串</returns>
  67. public static string GetFileSha1(this Stream fs) => HashFile(fs, "sha1");
  68. /// <summary>
  69. /// 计算文件的 sha256 值
  70. /// </summary>
  71. /// <param name="fs">源文件流</param>
  72. /// <returns>sha256 值16进制字符串</returns>
  73. public static string GetFileSha256(this Stream fs) => HashFile(fs, "sha256");
  74. /// <summary>
  75. /// 计算文件的 sha512 值
  76. /// </summary>
  77. /// <param name="fs">源文件流</param>
  78. /// <returns>sha512 值16进制字符串</returns>
  79. public static string GetFileSha512(this Stream fs) => HashFile(fs, "sha512");
  80. /// <summary>
  81. /// 计算文件的哈希值
  82. /// </summary>
  83. /// <param name="fs">被操作的源数据流</param>
  84. /// <param name="algo">加密算法</param>
  85. /// <returns>哈希值16进制字符串</returns>
  86. private static string HashFile(Stream fs, string algo)
  87. {
  88. using HashAlgorithm crypto = algo switch
  89. {
  90. "sha1" => SHA1.Create(),
  91. "sha256" => SHA256.Create(),
  92. "sha512" => SHA512.Create(),
  93. _ => MD5.Create(),
  94. };
  95. byte[] retVal = crypto.ComputeHash(fs);
  96. var sb = new StringBuilder();
  97. foreach (var t in retVal)
  98. {
  99. sb.Append(t.ToString("x2"));
  100. }
  101. return sb.ToString();
  102. }
  103. }
  104. }