| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace PTMedicalInsurance.Common
- {
- public static class Base64StreamingEncoder
- {
- /// <summary>
- /// 将文件以流式方式转换为 Base64 字符串(适用于大文件)
- /// </summary>
- /// <param name="inputFilePath">输入 ZIP 文件路径</param>
- /// <param name="outputWriter">输出目标(如 StreamWriter、StringWriter 或网络流)</param>
- /// <param name="chunkSize">每次读取的字节数(建议 3 的倍数,如 36864)</param>
- public static void ConvertToBase64Stream(string inputFilePath, TextWriter outputWriter, int chunkSize = 36864)
- {
- // 确保 chunkSize 是 3 的倍数,避免 Base64 编码时出现填充混乱(可选优化)
- if (chunkSize % 3 != 0)
- throw new ArgumentException("chunkSize 最好是 3 的倍数,以提高 Base64 效率。");
- byte[] buffer = new byte[chunkSize];
- int bytesRead;
- // 保留未完全编码的字节(用于跨块对齐)
- var leftoverBuffer = new byte[2]; // Base64 每 3 字节一组,最多余 2 字节
- int leftoverCount = 0;
- using (var fileStream = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read, bufferSize: 4096, useAsync: false))
- {
- while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
- {
- // 当前块 + 上次剩余字节,组成完整处理单元
- int totalAvailable = leftoverCount + bytesRead;
- var processBuffer = new byte[totalAvailable];
- Array.Copy(leftoverBuffer, 0, processBuffer, 0, leftoverCount);
- Array.Copy(buffer, 0, processBuffer, leftoverCount, bytesRead);
- // 计算可以完整编码的字节数(必须是 3 的倍数)
- int fullGroups = (totalAvailable / 3) * 3;
- int remaining = totalAvailable - fullGroups;
- // 编码完整组
- string encoded = Convert.ToBase64String(processBuffer, 0, fullGroups);
- outputWriter.Write(encoded);
- // 保存剩余字节(用于下一次)
- Array.Clear(leftoverBuffer, 0, leftoverBuffer.Length);
- Array.Copy(processBuffer, fullGroups, leftoverBuffer, 0, remaining);
- leftoverCount = remaining;
- }
- // 处理最后的剩余字节(会自动补 '=')
- if (leftoverCount > 0)
- {
- string final = Convert.ToBase64String(leftoverBuffer, 0, leftoverCount);
- outputWriter.Write(final);
- }
- }
- }
- }
- }
|