【问题标题】:Handle Convert.ToBase64String out of memory exception when converting to string转换为字符串时处理 Convert.ToBase64String 内存不足异常
【发布时间】:2018-07-22 10:44:43
【问题描述】:

当我尝试对包含一些视频的 .zip 文件夹执行以下操作时,我会出现内存不足的异常。

Byte[] bytes = File.ReadAllBytes(@"C:\folderWithVideos.zip");  
String base64File= Convert.ToBase64String(bytes);//<----- out of memory exception

如何正确处理这个异常?我的意思是没有try-catch,我尝试过类似的方法:

String base64File;
if (bytes.Length <= System.Int32.MaxValue)
   base64File = Convert.ToBase64String(bytes);

但它没有帮助,但 bytes.Length &lt;= 255 确实有帮助,但我不确定 255 是正确的数字。

【问题讨论】:

  • 您尝试 Base64 的 Zip 文件有多大?
  • 我很好奇你为什么要首先对文件进行编码。
  • 您的代码不会在 ReadAllBytes() 上崩溃的唯一原因是您在 64 位操作系统上运行程序。使用 Project > Properties > Build 选项卡并取消选中“Prefer 32-bit”以避免在 ToBase64String() 调用上崩溃。这段代码的实用性很低,任何需要吞下这条巨大字符串的程序都会以同样的方式烧毁。
  • @IOException 我们到了那个时候:-) 你写了一个经典的XY question。您不想将大文件转换为 b64。您想将大文件上传到需要 b64 格式的 API。现在...根据您调用 API 的方式(可能是 Web 服务),有可能解决这个问题,这是一个与您提出的问题不同的问题。
  • 不要整体读写,而是流式传输。所以创建一个文件流来打开文件,按块读取它(因为 Base64 通过将 3 个字节转换为 4 个字符,块大小必须能被 3 整除),将块转换为 Base64,将 Base64 字符串写入您的 API 网络流,继续下一个块等等。这样你的内存消耗就会受到块大小的限制。

标签: c#


【解决方案1】:

基于the blog 中显示的代码,以下代码有效。

// using  System.Security.Cryptography
private void ConvertLargeFile()
{
    //encode 
    var filein = @"C:\Users\test\Desktop\my.zip";
    var fileout = @"C:\Users\test\Desktop\Base64Zip";
    using (FileStream fs = File.Open(fileout, FileMode.Create))
    using (var cs = new CryptoStream(fs, new ToBase64Transform(),
                                                CryptoStreamMode.Write))

    using (var fi = File.Open(filein, FileMode.Open))
    {
        fi.CopyTo(cs);
    }
    // the zip file is now stored in base64zip    
    // and decode
    using (FileStream f64 = File.Open(fileout, FileMode.Open))
    using (var cs = new CryptoStream(f64, new FromBase64Transform(),
                                                CryptoStreamMode.Read))
    using (var fo = File.Open(filein + ".orig", FileMode.Create))
    {
        cs.CopyTo(fo);
    }
    // the original file is in my.zip.orig
    // use the commandlinetool 
    //  fc my.zip my.zip.orig 
    // to verify that the start file and the encoded and decoded file 
    // are the same
}

他的代码使用System.Security.Cryptography命名空间中的标准类,并使用CryptoStreamFromBase64Transform及其对应的ToBase64Transform

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 2011-08-30
    • 2011-04-13
    • 2014-07-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    相关资源
    最近更新 更多