基本上,我想从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您可以找到测试文件。真实的文件有点大,因此需要更多的时间。
上述代码没有按预期工作。它非常慢,提取的图像大多是黑色(被破坏)。
答案 0 :(得分:1)
为了对您的问题给出明确的答案,我需要查看您尝试阅读的XML。但是,有两点:
根据documentation的Convert.FromBase64String
:
FromBase64String方法用于处理包含要解码的所有数据的单个字符串。要从流中解码base-64字符数据,请使用System.Security.Cryptography.FromBase64Transform类。
因此,您的问题可能在于以块的形式解码内容而不是以块的形式读取内容。
您可以使用XmlReader.ReadElementContentAsBase64
或XmlReader.ReadElementContentAsBase64Async
来达到此目的。来自文档:
此方法读取元素内容,使用Base64编码对其进行解码,并将已解码的二进制字节(例如,内联Base64编码的GIF图像)返回到缓冲区。
事实上,文档中的示例演示了如何从XML文件中提取base64编码的图像,并将其以块的形式写入二进制文件。