使用缓冲区将byte []转换为Base64字符串(以避免OOM)

时间:2019-08-16 11:56:44

标签: c# base64

我需要将字节数组转换为Base64字符串。确实,这很容易。只需执行以下操作即可:

string resultBase64 = Convert.ToBase64String(byteArray);

就完成了,对吧?好吧,不是我的情况。显然,此应用程序必须在其上运行的服务器受到一些严格的限制,并且尝试转换20 MB文件会导致System.OutOfMemoryException。

我试图将byteArray切成块,并通过缓冲区获取Base64字符串。

int bufferSize = 3000;
System.Text.StringBuilder builder = new System.Text.StringBuilder();
for (int i = 0; i < byteArray.Length; i += bufferSize)
{
    int currentBufferSize = Math.Min(bufferSize, byteArray.Length - i);
    byte[] buffer = new byte[currentBufferSize];
    Array.Copy(byteArray, i, buffer, 0, currentBufferSize);
    builder.Append(Convert.ToBase64String(buffer));
}
string resultBase64 = builder.ToString();

但是,这也会引发OOM(我相信,因为StringBuilder.ToString上创建了一个新字符串,该字符串与构建器本身结合会导致OOM)。

以最少的内存使用量将byte[]转换为base64 string的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

如果您正在使用Json.NET将对象转换为JSON,那么事实证明该已经支持将字节数组转换为base64编码的字符串,并且这种方式不会不要占用太多内存。

诀窍是确保可以将生成的JSON直接流式传输到HTTP请求,而不是在发送之前在内存中生成整个请求。

public class TestModel
{
    public byte[] Bytes { get; set; }
}

public static void Main(string[] args)
{
    var model = new TestModel() { Bytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 } };

    var request = WebRequest.CreateHttp("...");
    request.Method = "POST";
    request.SendChunked = true;

    using (var streamWriter = new StreamWriter(request.GetRequestStream()))
    using (var writer = new JsonTextWriter(streamWriter))
    {
        new JsonSerializer().Serialize(writer, model);
    }
    var response = request.GetResponse();
}

这里的重点是request.SendChunked = true,以及我们在JsonTextWriter返回的流上打开新的request.GetRequestStream(),并使用JsonTextWriter进行序列化的事实。 / p>

相关问题