将zip文件编码为Base64

本文关键字:Base64 编码 文件 zip | 更新日期: 2023-09-27 18:01:38

我想解码zip文件为base64字符串。文件可以高达100 MB,得到OutOfMemory异常并重新启动Visual Studio。我的编码码:

public static string EncodeToBase64(string zipPath)
{
    using (FileStream fs = new FileStream(zipPath, FileMode.Open, FileAccess.Read))
    {
       byte[] filebytes = new byte[fs.Length];
       fs.Read(filebytes, 0, Convert.ToInt32(fs.Length));
       return Convert.ToBase64String(filebytes);
    }
}

我能做什么来解决这个问题?

将zip文件编码为Base64

不要试图在一个块中完成所有的事情。

从FileStream循环字节。获取三个字节的倍数并对其进行编码。一定要使用StringBuilder来构建输出。

[注:此答案假设您可以将最后的64进制字符串分成块处理,例如将每个块依次写入某种流]

如果您编写一个辅助方法来读取最大大小的byte[]块中的文件,则可以简化此操作,例如:

public static IEnumerable<byte[]> ReadFileInBlocks(string filename, int blockSize)
{
    byte[] buffer = new byte[blockSize];
    using (var file = File.OpenRead(filename))
    {
        while (true)
        {
            int n = file.Read(buffer, 0, buffer.Length);
            if (n == buffer.Length)
            {
                yield return buffer;
            }
            else if (n > 0) // Must be the last block in the file (because n != buffer.Length)
            {
                Array.Resize(ref buffer, n);
                yield return buffer;         // Just this last block to return,
                break;                       // and then we're done.
            }
            else // Exactly read to end of file in previous read, so we're already done.
            {
                break;
            }
        }
    }
}

然后你可以写一个简单的方法来返回一个base64字符串序列,依次从文件中的每个字节块转换而来:

public static IEnumerable<string> ToBase64Strings(string filename, int blockSize)
{
    return ReadFileInBlocks(filename, blockSize).Select(Convert.ToBase64String);
}

然后假设你有一种方法来处理每个转换后的base-64字符串块,这样做:

foreach (var base64String in ToBase64Strings(myFilename, 1024))
    process(base64String);

或者,您可以跳过中间的ReadFileInBlocks()方法,并将转换为64位字符串折叠到其中,如下所示:

public IEnumerable<string> ConvertToBase64StringInBlocks(string filename, int blockSize)
{
    byte[] buffer = new byte[blockSize];
    using (var file = File.OpenRead(filename))
    {
        while (true)
        {
            int n = file.Read(buffer, 0, buffer.Length);
            if (n == 0) // Exactly read to end of file in previous read, so we're already done.
            {
                break;
            }
            else
            {
                yield return Convert.ToBase64String(buffer, 0, n);
            }
        }
    }
}