将zip文件编码为Base64

时间:2014-05-05 12:06:10

标签: c# zip base64 encode

我想解码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);
    }
}

我该怎么做才能解决它?

2 个答案:

答案 0 :(得分:2)

不要试图在一个块中完成整个事情。

从FileStream循环遍历字节。抓取三个字节的倍数并对其进行编码。请务必使用StringBuilder来构建输出。

这将大大减少内存使用量。

答案 1 :(得分:0)

[注意:此答案假定您可以处理最后的基本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;
            }
        }
    }
}

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

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);
            }
        }
    }
}