如果我使用 ReadElementContentAsBase64,文件总是空的

file is always empty if I use ReadElementContentAsBase64

我正在使用 XmlReader 解析 XML 文档。其中一个节点包含 base64 编码数据,我想对其进行解码。这就是我所做的:

byte[] buffer = new byte[4096];
int readBytes = 0;
using (FileStream outputFile = File.OpenWrite (path))
using (BinaryWriter bw = new BinaryWriter (outputFile)) {
    while ((readBytes = reader.ReadElementContentAsBase64 (buffer, 0, 4096)) > 0) {
        bw.Write (buffer, 0, readBytes);
    }
}

但是文件是空的,文件大小为 0 kB。我也尝试过但没有成功:

byte[] buffer = new byte[4096];
int readBytes = 0;
FileStream outputFile = new FileStream (path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
BinaryWriter bw = new BinaryWriter (outputFile);
while ((readBytes = reader.ReadElementContentAsBase64 (buffer, 0, 4096)) > 0) {
    bw.Write (buffer, 0, readBytes);
}
outputFile.Close ();

我不明白。 readBytes 不为空,所以数据在这里。如果我临时将流保存为文件,然后 它就可以工作(所以我不使用 ReadElementContentAsBase64)。为此,我在 Mac 上使用 Xamarin Studio,此代码嵌入到 dll 中。

我是不是做错了什么或者这是一个错误?我遇到的问题是 ,但是一个空文件?这可能是什么原因?我可以检查什么?

编辑:

现在我在没有 BinaryWriter 的情况下尝试了它,但文件的大小仍然为 0 kB。在这里你可以看到 reader:

的实现
public async string CallWS(string path, CancellationToken cancelToken)
{
    XmlDocument soapEnvelop = new XmlDocument();
    soapEnvelop.LoadXml(someXMLDoc);

    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(webserviceAddress);
    webRequest.Headers.Add("SOAPAction", "http://schemas.xmlsoap.org/soap/envelope");
    webRequest.ContentType = "text/xml;charset=\"utf-8\"";
    webRequest.Accept = "text/xml";
    webRequest.Method = "POST";

    using (Stream stream = webrequest.GetRequestStream())
    {
        soapEnvelop.Save(stream);
    }

    using (var response = await webRequest.GetResponseAsync ())
    using (Stream stream = response.GetResponseStream ())
    return parser.GetDocument(stream, path);
}

public string GetDocument(Stream stream, string path)
{
    // read xml and save file
    using (XmlReader reader = XmlReader.Create(stream))
    {
        while (reader.Read())
        {
            if (reader.IsStartElement() && reader.NodeType == XmlNodeType.Element)
            {
                switch (reader.Name)
                {
                    case "Document":
                        reader.ReadToDescendant("cKey");
                        string ckey = reader.ReadInnerXml();
                        switch (ckey)
                        {
                            case "base64Content":
                                reader.ReadToNextSibling("cValue");
                                byte[] buffer = new byte[4096];
                                int readBytes = 0;
                                using (FileStream outputFile = File.OpenWrite(path))
                                {
                                    while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, 4096)) > 0)
                                    {
                                        outputFile.Write(buffer, 0, readBytes);
                                    }
                                }

                                break;
                            default:
                                break;
                        }

                        break;
                    default:
                        break;
                }
            }
        }
    }

    return path;
}

Windows 上似乎有一些 broken (or at least, inconsistent with .Net on Windows) with ReadElementContentAsBase64 on Xamarin.iOS. From your it appears that FromBase64Transform is available in your environment, so give this a try, it produces the same result as the 算法:

        // Advance to the text value of the element.
        if (reader.NodeType == XmlNodeType.Element)
            reader.Read();
        // But make sure there is text value!
        if (reader.NodeType == XmlNodeType.Text)
        {
            var charBuffer = new char[4096];
            using (var fileStream = File.OpenWrite(path))
            using (var transform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces))
            using (var cryptoStream = new CryptoStream(fileStream, transform, CryptoStreamMode.Write))
            using (var bufferedStream = new BufferedStream(cryptoStream, charBuffer.Length))
            {
                int charRead;
                while ((charRead = reader.ReadValueChunk(charBuffer, 0, charBuffer.Length)) != 0)
                {
                    for (int i = 0; i < charRead; i++)
                        bufferedStream.WriteByte(checked((byte)charBuffer[i]));
                }
            }
            Debug.WriteLine("Wrote " + path);
        }

在处理 WRITERS 时,有一个有用的方法 FLUSH 将数据发送到底层 STREAM。我不知道这对这种情况是否有帮助,但值得一试。

现在我尝试将文件保存在另一个目录中,但是在旧目录中却同时写入了。所以我从头开始检查我的代码并发现了问题:

XMLReader 完成其工作后,我将一个空字符串写入同一路径。哎哟!

现在文件写入正确,但内容错误(这是错误)。感谢所有试图帮助我的人!