【问题标题】:C# Decode Large/Huge XML / CDATA context in Base64C# 在 Base64 中解码大型/巨大的 XML / CDATA 上下文
【发布时间】:2012-10-04 00:28:01
【问题描述】:

我得到了一个非常大的 XML (>1GB),其中包含 CDATA 内容,包含 76 个字符和 CRLF 的 base64,最后一个内容用“=”填充,没有 CRLF。

获取 base64 解码的最自然方法是使用 XmlReader reader.ReadElementContentAsBase64(...) 但在 100Mb 时停止工作。 (=OOM)

我在寻找一种流式传输到 Base64 转换的方法后发现了这个。

string Original = "foo bar, this is an example";

byte[] ToBase64; string Decoded;

using ( MemoryStream ms = new MemoryStream() )  using ( CryptoStream cs = new CryptoStream( ms, new ToBase64Transform(),
                                                CryptoStreamMode.Write ) )  using ( StreamWriter st = new StreamWriter( cs ) )  {
    st.Write( Original );
    st.Flush();
    ToBase64 = ms.ToArray();  }

using ( MemoryStream ms = new MemoryStream( ToBase64 ) )  using ( CryptoStream cs = new CryptoStream( ms, new FromBase64Transform(), 
                                                    CryptoStreamMode.Read ) )  using ( StreamReader sr = new StreamReader( cs ) )      {
    Decoded = sr.ReadToEnd(); }

Console.WriteLine( Original );  Console.WriteLine( Encoding.Default.GetString( ToBase64 ) );  Console.WriteLine( Decoded ); 

这个例子有一个字符串作为输入,但我需要转换这个代码来处理一个文件并开始/停止从文件中的一个位置读取。

              CData Start                         CDataEnd
                  |                                 |
                  V                                 V

[xml..[Envelope]...[Body]base64 with 76 char + CRLF + padding "="...[/Body]...[/Envelope]

【问题讨论】:

  • 顺便说一句,我很想知道您为什么不使用 Linq to XML 可能是它具有处理大量数据的能力

标签: c# stream base64 out-of-memory buffer


【解决方案1】:

这是我能创造的最好的.. int readbytes = 0;

                long bytesToRead = (CDataEnd - CDataStart);
                using (CryptoStream cryptoStremFromBase64 = new CryptoStream(context.OutStream, new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces), CryptoStreamMode.Write))
                {


                    byte[] bytebuffer = new byte[bytesToRead % 10485760];
                    readbytes = context.InStream.Read(bytebuffer, 0, bytebuffer.Length);
                    cryptoStremFromBase64.Write(bytebuffer, 0, bytebuffer.Length);

                    while (context.InStream.Position < CDataEnd)
                    {
                        WriteToLog("Context.Instream.Position = " + context.InStream.Position.ToString(), context, startingTime);
                        byte[] bytebuffer2 = new byte[10485760];
                        readbytes = context.InStream.Read(bytebuffer2, 0, bytebuffer2.Length);
                        cryptoStremFromBase64.Write(bytebuffer2, 0, bytebuffer2.Length);
                    }


                    cryptoStremFromBase64.Flush();

                }

Context.InStream 是带有 base64 的 SOAP context.Outstream 是从base64转换后body的输出

有什么办法可以改善吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-29
    • 2014-07-22
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多