2008-09-29 4 views
1

У меня есть 7-8 xml файлов. Каждый из них имеет размер приблизительно 50 МБ. Каков наилучший способ слияния файлов программно на C# без получения исключения System.OutOfMemory? До сих пор я пробовал читать каждый файл в StringBuilder и помещать его в массив строковых построителей, но я все равно получаю исключение system.outofmemoery. Любая помощь?? Спасибо, -NimeshСлияние больших файлов в C#

+0

Без примера того, как вы будете сливаться, довольно сложно дать ответ, как указали некоторые люди. – 2008-09-29 16:26:24

+0

Название этого вопроса должно быть лучше: «Объединение больших XML-файлов в C#», поскольку, например, для слияния двоичных файлов потребуется совершенно другой подход. – Christian 2009-09-17 06:21:41

ответ

1

Лично я, когда есть работать с файлами XML (принудительная под угрозой физического насилия обычно), я делаю это:

  1. Загрузка каждого файла в .NET DataSet через DataSet.ReadXML()
  2. Объедините информацию (с помощью запросов DataSet).
  3. Запиши комбинированную DataSet в XML с помощью DataSet.WriteXML()

Тогда я агрессивно удалить Orginal файл XML и протирать секторы, где он существовал на диске, чтобы удалить скверну. :-)

3

Дело в том, что вы по-прежнему пытаетесь сохранить все содержимое в памяти. Вы хотите хранить только небольшую порцию в памяти за раз, а это означает использование потоков. Не читайте весь файл в памяти, не открывайте поток на нем и не читайте его из потока.

Проблема с xml заключается в том, что вы не можете просто добавить их друг к другу: вы разложите вложенность тегов. Поэтому вам нужно что-то узнать о структуре ваших xml-файлов, чтобы вы могли иметь представление о том, что делать в каждой файловой границе.

Если у вас есть что-то, что теоретически работает со StringBuilder, но на практике это происходит только из-за ограничений памяти, вы должны иметь возможность переводить методы StringBuilder .Append() и .AppendLine() в .Write() и .WriteLine() вызывает поток.

0

Это зависит от того, что вы подразумеваете под слиянием, так как вы не разместили никакой информации о схеме.

В простейшем случае однородных простых элементов в одном наборе вы просто просто присоединяетесь к новому файлу на диске, избегая много работы в памяти, гарантируя, что внешние содержащие элементы будут удалены и добавлены вокруг коллекции.

0

Не уверен, что вы подразумеваете под слиянием в этом случае. Вы имеете в виду простую конкатенацию файлов, или вы проверяете содержимое?

, например,

file1.xml

<items> 
    <item id="1"> 
     <name>Widget</name> 
    </item> 
    <item id="2"> 
     <name>Widget 2</name> 
    </item> 
</items> 

file2.xml

<items> 
    <item id="3"> 
     <name>Widget</name> 
    </item> 
    <item id="4"> 
     <name>Widget 2</name> 
    </item> 
</items> 

могут быть объединены, как

<items> 
    <item id="1"> 
     <name>Widget</name> 
    </item> 
    <item id="2"> 
     <name>Widget 2</name> 
    </item> 
</items> 
<items> 
    <item id="3"> 
     <name>Widget</name> 
    </item> 
    <item id="4"> 
     <name>Widget 2</name> 
    </item> 
</items> 

который является довольно тривиальным, или как

<items> 
    <item id="1"> 
     <name>Widget</name> 
    </item> 
    <item id="2"> 
     <name>Widget 2</name> 
    </item> 
    <item id="3"> 
     <name>Widget</name> 
    </item> 
    <item id="4"> 
     <name>Widget 2</name> 
    </item> 
</items> 

Это не так, учитывая количество данных, о которых вы говорите. Что ты имеешь в виду?

1

Укажите «merge».

Если вы хотите просто конкатенировать файлы, используйте StreamReader и читайте строки за строкой.

Если вы действительно хотите создать новый действительный xml, перейдите к XmlTextReader. Он не читает весь файл в памяти.

3

Детали того, что вам нужно для слияния, действительно жизненно необходимы. Однако, чтобы начать: вы, скорее всего, захотите XmlReader для каждого из входных файлов и XmlWriter для выходного файла. Это позволит вам передавать как входные, так и выходные данные.

Другой альтернативой может быть использование XStreamingElement из LINQ to XML. У меня нет опыта в этом, но, возможно, это будет более простой API.(Остальная часть LINQ to XML, безусловно, лучше, чем DOM API.)

0

Объединить их в файловой системе, вызвав команду «copy a.xml + b.xml» или вызывая API-интерфейсы файловой системы Windows, используемые « копировать ".