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);
}
}
}
}
}