将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);
}
}
我能做什么来解决这个问题?
不要试图在一个块中完成所有的事情。
从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);
}
}
}
}