首页 > 解决方案 > Convert.ToBase64String 为字节 [] 抛出“System.OutOfMemoryException”(文件:大尺寸)

问题描述

我正在尝试转换byte[]base64字符串格式,以便我可以将该信息发送给第三方。我的代码如下:

byte[] ByteArray = System.IO.File.ReadAllBytes(path);
string base64Encoded = System.Convert.ToBase64String(ByteArray);

我收到以下错误:

引发了“System.OutOfMemoryException”类型的异常。你能帮我吗 ?

标签: c#base64

解决方案


更新

我刚刚发现@PanagiotisKanavos 的评论指向Is there a Base64Stream for .NET? . 这与我下面的代码尝试实现的基本相同(即允许您处理文件而不必一次将整个内容保存在内存中),但没有自滚动代码的开销/风险/而不是使用这项工作的标准 .Net 库方法。


原来的

下面的代码将创建一个新的临时文件,其中包含输入文件的 Base64 编码版本。

这应该具有较低的内存占用,因为我们不是一次处理所有数据,而是一次处理几个字节。

为避免将输出保存在内存中,我已将其推送回临时文件,该文件将被返回。当您稍后需要将该数据用于其他过程时,您需要将其流式传输(即,这样您就不会一次使用所有这些数据)。

您还会注意到我使用WriteLineWrite; 这将引入非 base64 编码字符(即换行符)。这是故意的,因此如果您使用文本阅读器使用临时文件,您可以轻松地逐行处理它。
但是,您可以根据需要进行修改。

void Main()
{
    var inputFilePath = @"c:\temp\bigfile.zip";
    var convertedDataPath = ConvertToBase64TempFile(inputFilePath);
    Console.WriteLine($"Take a look in {convertedDataPath} for your converted data");
}

//inputFilePath = where your source file can be found.  This is not impacted by the below code
//bufferSizeInBytesDiv3  = how many bytes to read at a time (divided by 3); the larger this value the more memory is required, but the better you'll find performance.  The Div3 part is because we later multiple this by 3 / this ensures we never have to deal with remainders (i.e. since 3 bytes = 4 base64 chars)
public string ConvertToBase64TempFile(string inputFilePath, int bufferSizeInBytesDiv3 = 1024)
{
    var tempFilePath = System.IO.Path.GetTempFileName();
    using (var fileStream = File.Open(inputFilePath,FileMode.Open))
    {
        using (var reader = new BinaryReader(fileStream))
        {
            using (var writer = new StreamWriter(tempFilePath))
            {
                byte[] data;
                while ((data = reader.ReadBytes(bufferSizeInBytesDiv3 * 3)).Length > 0)
                {
                    writer.WriteLine(System.Convert.ToBase64String(data)); //NB: using WriteLine rather than Write; so when consuming this content consider removing line breaks (I've used this instead of write so you can easily stream the data in chunks later)
                }
            }
        }
    }
    return tempFilePath;
}

推荐阅读