转载: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. c#等待所有子线程执行完毕方法

    当我们在使用线程中,你会发现主线结束后子线程的结果才显示出来.现在我要等待所以子线程结束,然后在显示结果,怎么做呢? 方法如下: 1.使用 ManualResetEvent,代码如下:  using  ...

  2. SQL中取当前记录的ID----->SCOPE_IDENTITY()

    SQL Server 2000中,有三个比较类似的功能:他们分别是:SCOPE_IDENTITY.IDENT_CURRENT 和 @@IDENTITY,它们都返回插入到 IDENTITY 列中的值.I ...

  3. Mealy和moore型状态机

    Moore型状态机:下一状态只由当前状态决定,即次态=f(现状,输入),输出=f(现状): Mealy型状态机:下一状态不但与当前状态有关,还与当前输入值有关,即次态=f(现状,输入),输出=f(现状 ...

  4. Linux入门1

    在计算机科学中,Shell俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器).它类似于DOS下的command和后来的cmd.exe.它接收用户命令,然后调用相应的应用程序. Li ...

  5. oracle 日志学习(转载)

    一,重做日志概念 重做日志文件(redo log file)对于Oracle数据库至关重要.它们是数据库的事务日志.通常只用于恢复,不过也可以用于以下工作: q 系统崩溃后的实例恢复 q 通过备份恢复 ...

  6. 动态加载JS脚本的4种方法

    实现OPOA(One Page One Application)时,必须使用动态加载js. 也就是在用户选择某个菜单项后,再动态加载对应的全部js到客户端. 动态加载js的情况很多啊,比如解决ajax ...

  7. List使用Foreach 修改集合时,会报错的解决方案 (Error: Collection was modified; enumeration operation may not execute. ) - 摘自网络

    当用foreach遍历Collection时,如果对Collection有Add或者Remove操作时,会发生以下运行时错误: "Collection was modified; enume ...

  8. 问题-[DelphiXE2]提示第三控件不存在

    问题情况:在DelphiXE2启动时界面显示加载了控件,并且控件的路径也放在了环境变量中,但打开程序报第三控件不存在. 问题原因:是没有选择要加载的控件. 问题处理:点击Component->I ...

  9. excel函数

    120.623652,31.386228 120.623652 31.386228 上面数据要分成两列数据,我用了函数 =LEFT(C4,FIND(",",C4)-1),=RIGH ...

  10. maven依赖范围

    Scope: Compile:编译依赖,默认就是compile,在编译.测试.运行都有效 Test:测试依赖,仅测试有效 例如Junit Provided:已提供依赖范围.编译.测试有效,运行时候无效 ...