Ich habe Anforderungen, um große XML-Dateien (zwischen 0,5 MB - 600 MB) zu laden, Daten innerhalb der XML-Datei zu entschlüsseln und diese zu schreiben zu einem MemoryStream.Wie man eine XML-Datei streamen (laden) kann, XML-Elementdaten ändern und in MemoryStream schreiben
Es ist wichtig, dass die entschlüsselten Daten nicht auf der Festplatte liegen.
Unten ist meine aktuelle Implementierung, die das gesamte XML-Dokument in den Speicher lädt, die Kartennummer entschlüsselt und den Wert festlegt und dann das geänderte XML-Dokument in eine MemoryStream
kopiert. Diese Implementierung ist jedoch nicht durchführbar, da das gesamte XML-Dokument in den Arbeitsspeicher geladen wird.
public MemoryStream DecryptFile(string xmlFullPath, DateTime encryptionKey)
{
XNamespace xmlNameSpace = "http://www.xml.com/schema";
XDocument fileXDocument = XDocument.Load(xmlFullPath);
IEnumerable<XElement> cardElements =
fileXDocument
.Descendants(xmlNameSpace + "card");
// Iterate over each <card> element within the <batchRequest>.
foreach (XElement cardElement in cardElements)
{
XElement cardNumberElement = cardElement.Element(xmlNameSpace + "number");
// Read encrypted value
// Decrypt value
cardNumberElement.SetValue(decryptedCreditCard);
}
// Save the XML document, with the decrypted cards, to a memory stream.
var memoryStream = new MemoryStream();
fileXDocument.Save(memoryStream, SaveOptions.DisableFormatting);
// Rewind the stream, so that it's ready to be read from it elsewhere.
memoryStream.Position = 0;
return memoryStream;
}
Ich bin ziemlich vertraut mit den XmlReader
, und ich verwende es für andere Operationen.
Ich habe darüber nachgedacht, in der Lage zu sein, das XML-Dokument zu durchlaufen und Element-für-Element einfach in einen entsprechenden MemoryStream zu schreiben und schließlich die Daten zu entschlüsseln und in den Speicherstrom zu schreiben, wenn die Kartennummern erscheinen.
Ich bin jedoch nicht in der Lage, das rohe XML des Start/End-Elements zu erhalten, das ich bearbeite. Zumindest ohne das gesamte Element zu parsen/laden, was eine Operation wie ReadOuterXml ermöglicht. Aber ich möchte nicht das ganze Element lesen. Ich möchte einfach das rohe Element nach Element in den MemoryStream schreiben und nur die Kartennummer entschlüsseln, wenn ich auf sie stoße.
Beachten Sie, dass sich die Kartennummern in einem serialisierten Objekt "Transaktion" befinden. <transaction>...<number>asdfa3423jasfa</number></transaction>
Also, wie kann ich eine XML-Datei laden (streamen), Bit-Daten darin ändern und den Inhalt progressiv in einen MemoryStream schreiben?
Sie müssen dafür eine XML-Streaming-API verwenden. Versuchen Sie XmlTextReader. Sie wissen auch, dass MemoryStream auch alle gleichzeitig im Speicher ist, richtig? – hoodaticus
@hoodaticus yea in Bezug auf den MemoryStream, unsere Testshow, die den MemoryStream direkt im RAM hält, ist nicht so schlecht wie das Laden der gesamten XML im RAM. Die Ladder verursacht Speichermangel-Ausnahmen, während der MemoryStream in unserer Umgebung und den Einschränkungen in Ordnung ist. – contactmatt
Vergiss meinen XmlTextReader-Vorschlag nicht. Ich verwendete es für den Aufbau vollständig streambasierter Dienste - sehr schnelle und kleine, flache Speichernutzung war eine sehr gute Sache. – hoodaticus