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 { /// /// 将文件以流式方式转换为 Base64 字符串(适用于大文件) /// /// 输入 ZIP 文件路径 /// 输出目标(如 StreamWriter、StringWriter 或网络流) /// 每次读取的字节数(建议 3 的倍数,如 36864) 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); } } } } }