处理超过2 GB的字符串

时间:2011-09-05 08:52:19

标签: c# xml string excel

我有一个应用程序,其中打开了用户输入的大量数据的XLS文件,并将其中的数据转换为XML。我已经将XLS文件中的列映射到XML Maps。当我尝试在XMLMaps中使用ExportXml方法时,我得到一个包含XLS文件的正确XML表示的字符串。我解析了这个字符串并将其上传到我的服务器。

问题是,当我的XLS文件非常大时,为XML生成的字符串超过2 GB,我得到Out of Memory异常。我知道CLR对象的限制是2 GB。但就我而言,我需要处理这种情况。目前我只是要求用户发送更少的数据。

关于我如何做到这一点的任何想法?

编辑:

这只是我需要对生成的XML进行操作的一个例子。

  • 删除服务器数据不需要的某些字段。
  • 为每行数据添加ID号等内容。
  • 修改某些元素的值。
  • 对数据进行验证。

虽然XMLReader流是个好主意,但我无法通过该方法执行这些操作。虽然数据验证可以由Excel本身完成,但其他事情不能在这里完成。

使用XMLTextReader和XMLTextWriter并为每个步骤创建自定义方法是我想到的解决方案。但是要通过上面的jist,它需要XML文档经过或处理4次。这只是效率不高。

3 个答案:

答案 0 :(得分:5)

如果XML很大,那么您可以使用Export导出到临时文件,而不是将ExportXML用于字符串 - http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.xmlmap.export.aspx

如果您需要在C#中解析/处理XML,那么为了处理如此大的XML结构,您可能最好实现在流级别工作的自定义XMLReader(或XMLWriter)。请参阅此问题以获得一些类似的建议 - What is the best way to parse large XML (size of 1GB) in C#?

答案 1 :(得分:0)

我想如果你真的需要在RAM中保存整个东西,那么除了使用x64-OS和FX之外别无其他方法,但是使用其他方式处理像Stuart建议的数据可能是更好的方法。 ..

答案 2 :(得分:0)

您需要做的是使用“流链接”,即打开一个从excel文件读取的输入流和一个写入xml文件的输出流。然后,您的转换类/方法将两个流作为输入,并从输入流中读取足够的数据,以便能够写入输出。

编辑:非常简单的最小例子

从文件转换:

  123
  1244125
  345345345 
  4566
  11 

  <List>
      <ListItem>123</ListItem>
      <ListItem>1244125</ListItem>
      ...
  </List>
使用

  void Convert(Stream fromStream, Stream toStream)
  {
     using(StreamReader from= new StreamReader(fromStream))
     using(StreamWriter to = new StreamWriter(toStream))
     {
        to.WriteLine("<List>");
        while(!from.EndOfStream)
        {
            string bulk = from.ReadLine(); //in this case, a single line is sufficient
            //some code to parse the bulk or clean it up, e.g. remove '\r\n' 
            to.WriteLine(string.Format("<ListItem>{0}</ListItem>", bulk));
        }
        to.WriteLine("</List>"); 
      }

  }

  Convert(File.OpenRead("source.xls"), File.OpenWrite("source.xml"));

当然,你可以用更加抽象的方式做到这一点,但这只是为了表明我的观点