从XmlReader读取流,base64解码并将结果写入文件

时间:2015-05-07 13:30:18

标签: c# xml base64 xmlreader

基本上,我想从XmlReader中提取流,然后直接将其解码为文件。

可以看到XML文件的结构here。要获得值,我必须使用ReadInnerXml()。是否可以使用ReadValueChunk代替?

这是我目前的代码:

using (XmlReader reader = XmlReader.Create("/your/path/47311.xml"))
{
    while(reader.Read())
    {
        if (reader.IsStartElement () && reader.NodeType == XmlNodeType.Element) {
            switch (reader.Name) {
            case "ttOutputRow":
                reader.ReadToDescendant ("cKey");
                switch (reader.ReadInnerXml ()) {
                case "findMe":
                    reader.ReadToNextSibling ("cValue");
                    // here begins the interesting part
                    char[] buffer = new char[4096];
                    int charRead;
                    using (var destStream = File.OpenWrite ("/your/path/47311.jpg")) {
                        while ((charRead = reader.ReadValueChunk (buffer, 0, 4096)) != 0) {
                            byte[] decodedStream = System.Convert.FromBase64String (new string (buffer));
                            await destStream.WriteAsync(decodedStream, 0, decodedStream.Length);
                            Console.WriteLine ("in");
                        }

                    }
                    break;
                default:
                    break;
                }
                break;
            default:
                break;
            }
        }
    }
}

目前,他没有读取该值。

我不能使用ReadValueChunk吗?如何在不牺牲太多内存的情况下直接使用XmlReader中的流?

修改

根据dbc我修改了我的代码。这就是我目前使用的:

using (XmlReader reader = XmlReader.Create("test.xml"))
{
    while(reader.Read())
    {
        if (reader.IsStartElement () && reader.NodeType == XmlNodeType.Element) {
            switch (reader.Name) {
            case "ttOutputRow":
                reader.ReadToDescendant ("cKey");
                switch (reader.ReadInnerXml ()) {
                case "findMe":
                    reader.ReadToNextSibling ("cValue");
                    byte[] buffer = new byte[40960];
                    int readBytes = 0;
                    using (FileStream outputFile = File.OpenWrite ("test.jpg")) 
                    using (BinaryWriter bw = new BinaryWriter(outputFile))
                    {
                        while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, 40960)) > 0) {
                            bw.Write (buffer, 0, readBytes);
                            Console.WriteLine ("in");
                        }

                    }
                    break;
                default:
                    break;
                }
                break;
            default:
                break;
            }
        }
    }
}

Here您可以找到测试文件。真实的文件有点大,因此需要更多的时间。

上述代码没有按预期工作。它非常慢,提取的图像大多是黑色(被破坏)。

1 个答案:

答案 0 :(得分:1)

为了对您的问题给出明确的答案,我需要查看您尝试阅读的XML。但是,有两点:

  1. 根据documentationConvert.FromBase64String

      

    FromBase64String方法用于处理包含要解码的所有数据的单个字符串。要从流中解码base-64字符数据,请使用System.Security.Cryptography.FromBase64Transform类。

    因此,您的问题可能在于以块的形式解码内容而不是以块的形式读取内容。

  2. 您可以使用XmlReader.ReadElementContentAsBase64XmlReader.ReadElementContentAsBase64Async来达到此目的。来自文档:

      

    此方法读取元素内容,使用Base64编码对其进行解码,并将已解码的二进制字节(例如,内联Base64编码的GIF图像)返回到缓冲区。

    事实上,文档中的示例演示了如何从XML文件中提取base64编码的图像,并将其以块的形式写入二进制文件。