从 XmlReader 读取流,base64 解码并将结果写入文件
Read stream from XmlReader, base64 decode it and write result to file
基本上,我想从 XmlReader
中提取流并直接将其 base64 解码为文件。
可以看到XML文件的结构。要获得我必须使用 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你可以找到一个测试文件。实际文件稍微大一点,因此需要更多时间。
以上代码没有按预期工作。速度很慢,提取的图像大部分是黑色的(已损坏)。
为了对您的问题给出明确的答案,我需要查看您正在尝试阅读的 XML。不过,有两点:
根据documentation for Convert.FromBase64String
:
The FromBase64String method is designed to process a single string that contains all the data to be decoded. To decode base-64 character data from a stream, use the System.Security.Cryptography.FromBase64Transform class.
因此,您的问题可能出在以块的形式解码内容而不是以块的形式读取内容。
您可以使用 XmlReader.ReadElementContentAsBase64
or XmlReader.ReadElementContentAsBase64Async
来达到这个目的。来自文档:
This method reads the element content, decodes it using Base64 encoding, and returns the decoded binary bytes (for example, an inline Base64-encoded GIF image) into the buffer.
事实上,文档中的示例演示了如何从 XML 文件中提取 base64 编码的图像并将其写入块中的二进制文件。
基本上,我想从 XmlReader
中提取流并直接将其 base64 解码为文件。
可以看到XML文件的结构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你可以找到一个测试文件。实际文件稍微大一点,因此需要更多时间。
以上代码没有按预期工作。速度很慢,提取的图像大部分是黑色的(已损坏)。
为了对您的问题给出明确的答案,我需要查看您正在尝试阅读的 XML。不过,有两点:
根据documentation for
Convert.FromBase64String
:The FromBase64String method is designed to process a single string that contains all the data to be decoded. To decode base-64 character data from a stream, use the System.Security.Cryptography.FromBase64Transform class.
因此,您的问题可能出在以块的形式解码内容而不是以块的形式读取内容。
您可以使用
XmlReader.ReadElementContentAsBase64
orXmlReader.ReadElementContentAsBase64Async
来达到这个目的。来自文档:This method reads the element content, decodes it using Base64 encoding, and returns the decoded binary bytes (for example, an inline Base64-encoded GIF image) into the buffer.
事实上,文档中的示例演示了如何从 XML 文件中提取 base64 编码的图像并将其写入块中的二进制文件。