The class System.Convert provide two basic methods "ToBase64String()" and "Convert.FromBase64String()" to encode a byte array to a base64 string and decode a base64 string to a byte array.
It is very good to use them to encode and decode base64. But in some case, it is a disaster.
For example, if you want to encode a 4 gb file to base64, the code above must throw an OutOfMemory exception., because you must read the file into a byte array. So we need to look for another way to e
The class System.Convert provide two basic methods "ToBase64String()" and "Convert.FromBase64String()" to encode a byte array to a base64 string and decode a base64 string to a byte array.
public string Encode(byte[] data)
  {
return Convert.ToBase64String(data);
}
public byte[] Decode(string strBase64)
  {
return Convert.FromBase64String(strBase64);
}
It is very good to use them to encode and decode base64. But in some case, it is a disaster.
For example, if you want to encode a 4 gb file to base64, the code above must throw an OutOfMemory exception., because you must read the file into a byte array. So we need to look for another way to encode and decode by base64.
Long days ago, a man have posted an article about how to deal with it.
http://blogs.microsoft.co.il/blogs/kim/archive/2007/10/09/base64-encode-large-files-very-large-files.aspx
This man use XmlWriter to work around it.
By researching the basis of the Base64 encoding in rfc, I found another more directly way to deal with it.
According rfc3548, base64 encode data in the unit of 3 bytes to 4 bytes, if the last part's length is less than 3,
the char '=' will be padded. So we can encode file in small chunks whose size is 3, then we can get the encoding data of the file by combiling encoding data of every chunks.
So I have below code:
public void EncodeFile(string inputFile, string outputFile)
  {
using(FileStream inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read))
 {
using(StreamWriter outputWriter = new StreamWriter(outputFile, false, Encoding.ASCII))
 {
byte[] data = new byte[3 * 1024]; //Chunk size is 3k
int read = inputStream.Read(data, 0, data.Length);
while(read > 0)
 {
outputWriter.Write(Convert.ToBase64String(data, 0, read));
read = inputStream.Read(data, 0, data.Length);
}
outputWriter.Close();
}
inputStream.Close();
}
}

public void DecodeFile(string inputFile, string outputFile)
 {
using (FileStream inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read))
 {
using (FileStream outputStream = File.Create(outputFile))
 {
byte[] data = new byte[4 * 1024]; //Chunk size is 4k
int read = inputStream.Read(data, 0, data.Length);

byte[] chunk = new byte[3 * 1024];
while (read > 0)
 {
chunk = Convert.FromBase64String(Encoding.ASCII.GetString(data, 0, read));
outputStream.Write(chunk, 0, chunk.Length);
read = inputStream.Read(data, 0, data.Length);
}

outputStream.Close();
}

inputStream.Close();
}
}
These methods also can be improved to support mime format (76 chars per line).
public static void EncodeFile(string inputFile, string outputFile)
 {
using(FileStream inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read, FileShare.Read))
 {
using(StreamWriter outputWriter = new StreamWriter(outputFile, false, Encoding.ASCII))
 {
byte[] data = new byte[57 * 1024]; //Chunk size is 57k
int read = inputStream.Read(data, 0, data.Length);
while(read > 0)
 {
outputWriter.WriteLine(Convert.ToBase64String(data, 0, read, Base64FormattingOptions.InsertLineBreaks));
read = inputStream.Read(data, 0, data.Length);
}
outputWriter.Close();
}
inputStream.Close();
}
}

public static void DecodeFile(string inputFile, string outputFile)
 {
using (StreamReader reader = new StreamReader(inputFile, Encoding.ASCII, true))
 {
using (FileStream outputStream = File.Create(outputFile))
 {
string line = reader.ReadLine();

while (!string.IsNullOrEmpty(line))
 {
if (line.Length > 76)
throw new InvalidDataException("Invalid mime-format base64 file");

byte[] chunk = Convert.FromBase64String(line);
outputStream.Write(chunk, 0, chunk.Length);
line = reader.ReadLine();
}

outputStream.Close();
}

reader.Close();
}
}
|
|
好久没更新BLOG了, 今天来篇英文的文章,真是倍感吃力阿。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架