如何在不分配总大小数组的情况下拼接三个Byte数组并Base64编码?
问题
现有如下C#代码:
private static string GetEncryptedContent(byte[] arrayA, byte[] arrayB, byte[] arrayC) { var concatenatedArray = new byte[arrayB.Length + arrayC.Length + arrayA.Length]; Buffer.BlockCopy(arrayB, 0, concatenatedArray, 0, arrayB.Length); Buffer.BlockCopy(arrayC, 0, concatenatedArray, arrayB.Length, arrayC.Length); Buffer.BlockCopy(arrayA, 0, concatenatedArray, arrayC.Length + arrayB.Length, arrayA.Length); return Convert.ToBase64String(concatenatedArray); }
这段代码通过分配一个总长度的数组拼接三个byte[]后再执行Base64编码。请问有没有办法不用分配这个总大小的数组就能完成Base64编码?
解答
当然可以,用流式处理就能避免一次性分配大内存。Base64编码是按3字节一组转换为4个字符的,我们可以利用.NET内置的CryptoStream和ToBase64Transform来分批次处理多个字节数组,完全不需要提前拼接成完整数组。
直接上实现代码:
private static string GetEncryptedContent(byte[] arrayA, byte[] arrayB, byte[] arrayC) { using var outputStream = new MemoryStream(); using var base64EncoderStream = new CryptoStream(outputStream, new ToBase64Transform(), CryptoStreamMode.Write); // 按顺序写入三个字节数组,编码器会自动处理分块转换 base64EncoderStream.Write(arrayB, 0, arrayB.Length); base64EncoderStream.Write(arrayC, 0, arrayC.Length); base64EncoderStream.Write(arrayA, 0, arrayA.Length); base64EncoderStream.FlushFinalBlock(); // 必须调用,处理最后不足3字节的剩余数据并补填充符 outputStream.Position = 0; using var streamReader = new StreamReader(outputStream); return streamReader.ReadToEnd(); }
关键细节说明
ToBase64Transform负责Base64的核心转换逻辑,CryptoStream会把写入的字节分块传给它,处理后的结果直接写入目标流,全程不需要把所有数据加载到内存中。- 内存占用仅和编码器的内部缓冲区大小有关(默认是1024字节级别),和三个数组的总长度无关,特别适合处理大体积数据。
- 必须调用
FlushFinalBlock,因为Base64需要对最后一组不足3字节的数据做特殊处理,添加必要的填充符=,否则编码结果会不完整。
如果不想用CryptoStream,也可以手动实现分块处理逻辑,但内置实现已经经过优化,可靠性更高,没必要重复造轮子。
内容的提问来源于stack exchange,提问作者gdoron
相关产品推荐
相关产品推荐

