解码大型Base64字符串

时间:2015-01-23 08:05:44

标签: c# base64 out-of-memory

我有一个来自WebService的输入字符串,其形式为大约70 MB的大型base64编码字符串。

我想将其解码为一个文件,并尝试使用Convert.FromBase64String()

然而,

这会产生OutOfMemoryException。经过一些阅读,我发现了与Base64有关的Convert方法

  

泄漏内存(毫无疑问是由于字符串的不可变性和框架方法中的一些不良设计)    source

并且有一个方便的"流式传输" System.Security.Cryptography命名空间中的替换:FromBase64Transform

所以,我决定尝试一下,但是我需要输入一个byte的数组,我没有 - 我有一个字符串。

如何将string我的byte转换为OutOfMemoryException而不会再次遇到 转换的另一个{{1}}?

2 个答案:

答案 0 :(得分:2)

虽然您可能可以将字符串转换为内存中的字节数组,而不必担心内存使用情况,但您可以通过以下方式流式传输转换:

var input = "abcdefghijklmnop";
byte[] output;
using (var ms = new MemoryStream())
using (var cs = new CryptoStream(ms, new FromBase64Transform(), CryptoStreamMode.Write))
using (var tr = new StreamWriter(cs))
{
    tr.Write(input);
    tr.Flush();
    output = ms.ToArray();
}

如果您使用合适的MemoryStream替换FileStream,则可以直接流式传输到文件而不是数组:

var input = new string('a', 400000000);
byte[] output;
using (var ms = new FileStream(Guid.NewGuid().ToString() + ".bin", FileMode.Create))
using (var cs = new CryptoStream(ms, new FromBase64Transform(), CryptoStreamMode.Write))
using (var tr = new StreamWriter(cs))
{
    tr.Write(input);
    tr.Flush();
}

答案 1 :(得分:1)

您应该使用Encoding.ASCII.GetBytes()或类似字符串将您的字符串转换回用于传输base64编码数据的原始ASCII。

我很好奇你是如何从WebService收到字符串的。是否有可能跳过转换为.NET字符串并将直接接收的字节传递给转换?那会更有效率。