[英]c# How to read a single file with normal and xml text elements
我從Web服務接收數據流並嘗試將流的內容保存到文件。 該流包含標准的文本行以及大塊的xml數據(在一行上)。 文件大小約為800Mb。
問題:處理每行的xml部分時收到內存不足異常。
==start file
line 1
line 2
<?xml version=.....huge line etc</xml>
line 3
line4
<?xml version=.....huge line etc</xml>
==end file
當前代碼,正如您在巨大的xml行中讀取時所看到的那樣,它會激活內存。
string readLine;
using (StreamReader reader = new StreamReader(downloadStream))
{
while ((readLine = reader.ReadLine()) != null)
{
streamWriter.WriteLien(readLine); //writes to file
}
}
我試圖想出一個解決方案,我將TextReader / StreamReader和XmlTextReader結合使用來處理每個部分。 當我到達xml部分時,我可以切換到XmlTextReader並使用Read()方法讀取每個節點,從而停止內存峰值。
有關如何做到這一點的任何建議? 或者,我可以創建一個能夠讀取這些行的自定義XmlTextReader嗎? 有什么指針嗎?
更新
另一個問題是,我需要重新讀取此文件並拆分兩個xml部分以分隔xml文件! 我轉換了解決方案,使用二進制編寫器編寫文件,然后開始使用二進制讀取器讀回文件。 我有文本處理來檢測xml部分的開始,具體是哪個xml部分,所以我可以將它映射到正確的文件! 但是,這會導致讀取二進制文件並進行檢測時出現問題...
using (BinaryReader reader = new BinaryReader(savedFileStream))
{
while ((streamLine = reader.ReadString()) != null)
{
if (streamLine.StartsWith("<?xml version=\"1.0\" ?><tag1"))
//xml file 1
else if (streamLine.StartsWith("<?xml version=\"1.0\" ?><tag2"))
//xml file 2
XML可能包含所有內容作為一行,因此您可能最好使用二進制讀取器/寫入器,您可以在其中決定讀/寫大小。
下面是一個例子,這里我們為每次迭代讀取BUFFER_SIZE個字節:
Stream s = new MemoryStream();
Stream outputStream = new MemoryStream();
int BUFFER_SIZE = 1024;
using (BinaryReader reader = new BinaryReader(s))
{
BinaryWriter writer = new BinaryWriter(outputStream);
byte[] buffer = new byte[BUFFER_SIZE];
int read = buffer.Length;
while(read != 0)
{
read = reader.Read(buffer, 0, BUFFER_SIZE);
writer.Write(buffer, 0, read);
}
writer.Flush();
writer.Close();
}
我不知道這是否會導致您編碼等問題,但我認為您必須將文件讀取為二進制文件。
如果您只想將一個流復制到另一個流而不修改數據,則不需要Stream文本或二進制幫助程序(StreamReader,StreamWriter,BinaryReader,BinaryWriter等),只需復制流即可。
internal static class StreamExtensions
{
public static void CopyTo(this Stream readStream, Stream writeStream)
{
byte[] buffer = new byte[4096];
int read;
while ((read = readStream.Read(buffer, 0, buffer.Length)) > 0)
writeStream.Write(buffer, 0, read);
}
}
我認為有內存泄漏
處理幾行后或第一行本身是否會出現內存異常?
並且while循環中沒有streamWriter.Flush()。
你不覺得應該有嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.