2015-05-08 4 views
0

Я использую XmlReader для анализа XML-документа. Один из узлов содержит данные, закодированные в base64, и я хочу их декодировать. Это то, что я делаю:Файл всегда пуст, если я использую ReadElementContentAsBase64

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 не пуст, поэтому данные здесь. Если я временно сохраняю поток как файл и convert, тогда он работает (поэтому я не использую ReadElementContentAsBase64). Я использую Xamarin Studio на Mac для этого, и этот код встроен в dll.

Я делаю что-то неправильно или это ошибка? У меня была проблема, что decoding doesn't work correctly, но пустой файл? Что может быть причиной этого? Что я могу проверить?

Edit:

Теперь я попробовал без BinaryWriter, но файл имеет еще размер 0 Кб. Здесь вы можете увидеть реализацию с читателя:

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; 
} 
+0

Мы понятия не имеем, откуда берется «читатель». Пожалуйста, покажите короткую, но полную программу, демонстрирующую проблему, имея в виду, что нам действительно не нужно видеть, что вы делаете * с результатами, за исключением того, что они максимально точно показывают их правильность. –

+0

Кроме того, непонятно, почему вы используете 'BinaryWriter' вообще ... почему бы просто не написать в поток? –

+0

Я использовал 'BinaryWriter', потому что он был в [example] (https://msdn.microsoft.com/en-us/library/system.xml.xmlreader.readelementcontentasbase64%28v=vs.110%29.aspx) , Я обновил свой вопрос, чтобы показать вам * читателя *. Я получаю поток в эту функцию. Если вам нужно, я могу показать некоторые подробности о потоке. Спасибо за вашу помощь! – testing

ответ

0

Теперь я попытался сохранить файл в другом каталоге, но в старом каталоге там было написано в одно и то же время. Таким образом, я начал с моего кода с самого начала и нашел проблему:

Я писал пустую строку в тот же путь после того, как XMLReader выполнил свою работу. Ой!

Теперь файл написан правильно, но с неправильным контентом (это ошибка). Спасибо всем, кто пытался мне помочь!

0

Кажется, как будто что-то broken (или, по крайней мере, несовместимым с .Net на Windows) с ReadElementContentAsBase64 на Xamarin.iOS. Из вашего earlier question оказывается, что FromBase64Transform доступен в вашей среде, чтобы дать этому попытку, это дает тот же результат, как ReadElementContentAsBase64 алгоритма на Windows:

 // 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); 
     } 
0

Когда имеешь дело с ПИСАТЕЛЕЙ есть полезный метод FLUSH, который отправляет данные в базовые STREAM. Я не знаю, поможет ли это в этом случае, но стоит попробовать.

+0

Интересно. В течение короткого времени у него был правильный размер файла, но потом он снова изменился на ноль. – testing

Смежные вопросы