转载:http://www.cnblogs.com/jzywh/archive/2008/04/20/base64_encode_large_file.html

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

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

 

Base64 encode/decode large file的更多相关文章

  1. node_nibbler:自定义Base32/base64 encode/decode库

    https://github.com/mattrobenolt/node_nibbler 可以将本源码复制到自己需要的JS文件中,比如下面这个文件,一个基于BASE64加密请求参数的REST工具: [ ...

  2. javascript base64 encode decode 支持中文

    * 字符编码 ** 一定要知道数据的字符编码 ** 使用utf-8字符编码存储数据 ** 使用utf-8字符编码输出数据 * Crypto.js 支持中文 Base64编码说明 Base64编码要求把 ...

  3. BASE64 Encode Decode

    package com.humi.encryption; import java.io.IOException; import java.io.UnsupportedEncodingException ...

  4. python encode decode unicode区别及用法

    decode 解码 encode 转码 unicode是一种编码,具体可以百度搜 # coding: UTF-8 u = u'汉' print repr(u) # u'\u6c49' s = u.en ...

  5. java URLEncoder 和Base64.encode()

    参考: http://www.360doc.com/content/10/1103/12/1485725_66213001.shtml (URLEncode) http://blog.csdn.net ...

  6. python编码问题之\"encode\"&\"decode\"

    python encode decode 编码 decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换 ...

  7. python编码encode decode(解惑)

    关于python 字符串编码一直没有搞清楚,今天总结了一下. Python 字符串类型 Python有两种字符串类型:str 与 unicode. 字符串实例 # -*- coding: utf-8 ...

  8. (转)Integrating Intel® Media SDK with FFmpeg for mux/demuxing and audio encode/decode usages 1

    Download Article and Source Code Download Integrating Intel® Media SDK with FFmpeg for mux/demuxing ...

  9. python3.3 unicode(encode&decode)

    最近在用python写多语言的一个插件时,涉及到python3.x中的unicode和编码操作,本文就是针对编码问题研究的汇总,目前已开源至github.以下内容来自项目中的README. 1 ASC ...

随机推荐

  1. 找出Java进程中大量消耗CPU

    原文:https://github.com/oldratlee/useful-shells useful-shells 把平时有用的手动操作做成脚本,这样可以便捷的使用. show-busy-java ...

  2. C# 日期转换为中文大写

    /// <summary> /// 日期转换为中文大写 /// </summary> public class UpperConvert { public UpperConve ...

  3. Ubuntu下添加Eclipse快捷方式

    首先是在/usr/share/applications下创建eclipse.desktop文件 1. 创建并编辑eclipse.desktop sudo vim /usr/share/applicat ...

  4. opencv保存选择图像中的区域(二)

    /* * ===================================================================================== * * Filen ...

  5. mac os 常用终端软件工具

    1. homebrew 安装 网上很多版本返回400错误,以下为最新版本地址(2015/02/09) ruby -e "$(curl -fsSL https://raw.githubuser ...

  6. linux进程的几种状态

    Linux是一个多用户,多任务的系统,可以同时运行多个用户的多个程序,就必然会产生很多的进程,而每个进程会有不同的状态. Linux进程状态:R (TASK_RUNNING),可执行状态. 只有在该状 ...

  7. Git 远程分支的查看及相关问题

    命令:git ls-remote -t 或者 git ls-remote --tag 运行结果如下: 0975ebc0f9a6b42ecbe066a50a26a678a0753b4d refs/tag ...

  8. CF29D - Ant on the Tree(DFS)

    题目大意 给定一棵树,要求你按给定的叶子节点顺序对整棵树进行遍历,并且恰好经过2*n-1个点,输出任意一条符合要求的路径 题解 每次从叶子节点开始遍历到上一个叶子节点就OK了, 这个就是符合要求的路径 ...

  9. Call Hierarchy(方法调用层次)

    在VS2010中的一项新功能:Call Hierarchy窗口,它可以审查代码,确定方法在哪里调用,以及它们与其他方法的关系. 打开一个类文件,找有方法体实现代码的方法,右键选择View Call H ...

  10. 小波变换和motion信号处理(二)(转)

    写的太好,这是第二篇:http://www.kunli.info/2011/02/18/fourier-wavelet-motion-signal-2/ 这是<小波变换和motion信号处理&g ...