我正在从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
答案 0 :(得分: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();
}
我不知道这是否会导致编码等问题,但我认为您必须将文件读取为二进制文件。
答案 1 :(得分:1)
如果您只想将一个流复制到另一个流而不修改数据,则不需要Stream文本或二进制助手(StreamReader,StreamWriter,BinaryReader,BinaryWriter等),只需复制流即可。< / p>
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);
}
}
答案 2 :(得分:0)
我认为存在内存泄漏
处理几行后或第一行本身是否会出现内存异常?
并且while循环中没有streamWriter.Flush()。
你不觉得应该有吗?