【问题标题】:Handling strings more than 2 GB处理超过 2 GB 的字符串
【发布时间】:2011-09-05 08:52:18
【问题描述】:

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

问题是,当我的 XLS 文件非常大时,为 XML 生成的字符串超过 2 GB,并且出现内存不足异常。我了解 CLR 对象的限制为 2 GB。但就我而言,我需要处理这种情况。目前我只是发消息要求用户发送更少的数据。

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

编辑:

这只是我需要对生成的 XML 进行的操作的简要说明。

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

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

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

【问题讨论】:

  • 你能举一个你的xml内容的例子吗?
  • 编辑标签以包含 Excel,因为您是从 Excel 导出的。还删除了 CLR,因为这个问题与特定的运行时或低级代码没有太大关系。如果您不同意,请随时再次编辑或回滚。
  • @Jon Egerton:类似于当年的销售订单。希望你明白了。
  • 您不能将内容分成可管理大小的片段吗?
  • 当你说你需要“删除某些字段”时,有多少整体数据被删除了?如果您要删除大量数据,请在导出到 XML 之前在 Excel 中执行此操作。这可能有助于将您的内存保持在 2GB 以内

标签: c# xml string excel


【解决方案1】:

如果 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#?

【讨论】:

  • 我已经添加了我需要做的进一步处理的 jist。
  • 不确定您现在在寻找什么...取决于您的客户是什么 - 是 Silverlight 吗? WPF?表格?命令行?您的一个选择可能是在执行 xml 工作之前将某种数据 api 直接用于 excel 电子表格 - 例如您可以将 ADO.Net 之类的东西与 Excel 一起使用 - 但这确实取决于您的客户端应用程序及其环境
【解决方案2】:

如果您确实需要将整个内容保存在 RAM 中,我想没有其他方法可以使用 x64-OS 和 FX,但是使用 Stuart 建议的其他方法来处理数据可能是更好的方法。 ..

【讨论】:

    【解决方案3】:

    您需要做的是使用“流链接”,即打开一个从您的 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"));
    

    当然你可以用更优雅、更抽象的方式来做这件事,但这只是为了说明我的观点

    【讨论】:

    • 您是在谈论创建我自己的方法/类来将 excel 数据映射到所需的架构并生成 xml 文件吗?
    • 是的,就像 ConvertXMLToExcel(Stream input, Stream output),你可以简化为 StreamReader 输入和 StreamWriter 输出。然后在你的函数中,你需要创建一个循环,从输入流中读取足够多的内容,以便能够写入输出流。
    • 我对问题进行了一些编辑以添加更多详细信息。请检查一下。无法使用此解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-27
    相关资源
    最近更新 更多