C# 将zip文件编码为Base64

C# 将zip文件编码为Base64,c#,zip,base64,encode,C#,Zip,Base64,Encode,我要将zip文件解码为base64字符串。文件的大小可以达到100 MB,并退出内存异常并重新启动VisualStudio。我的编码代码: public static string EncodeToBase64(string zipPath) { using (FileStream fs = new FileStream(zipPath, FileMode.Open, FileAccess.Read)) { byte[] filebytes = new byte[f

我要将zip文件解码为base64字符串。文件的大小可以达到100 MB,并退出内存异常并重新启动VisualStudio。我的编码代码:

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

我能做些什么来解决它呢?

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

循环浏览文件流中的字节。获取三个字节的倍数并对其进行编码。确保使用StringBuilder生成输出

这将大大减少内存使用。

[注意:此答案假设您可以分块处理最终的base 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;
            }
        }
    }
}
或者,您可以跳过中间层
ReadFileInBlocks()
方法,并将转换为base 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);
            }
        }
    }
}
public IEnumerable ConvertToBase64StringInBlock(字符串文件名,int blockSize)
{
字节[]缓冲区=新字节[块大小];
使用(var file=file.OpenRead(文件名))
{
while(true)
{
int n=file.Read(buffer,0,buffer.Length);
若(n==0)//在上一次读取中精确读取到文件的末尾,那个么我们已经完成了。
{
打破
}
其他的
{
产生返回Convert.tobase64字符串(缓冲区,0,n);
}
}
}
}

100 MB应该不是问题。你的内存满了吗?另外,您是否需要base64字符串“在代码中”,或者您是否正在将其保存/发送到某个地方?如果您再次这样做,并且againI的内存非常不足,那么100MB很容易成为问题,但当编码到base64时,RAM会快速增加。用于保存和发送的base64字符串在32位程序运行了一段时间并有机会分割地址空间(与RAM无关)后,分配90 MB很容易失败。在程序真正内存不足之前,已经没有足够大的洞来容纳分配了。否则,一个在C#中很容易解决的问题就是允许程序作为64位进程运行。Matthew Watson,如何将Base64字符串解码为zip文件?
foreach (var base64String in ToBase64Strings(myFilename, 1024))
    process(base64String);
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);
            }
        }
    }
}