Как сортировать большой csv-файл без загрузки в память

У меня есть 20Gb + csv-файл, как это:

**CallId,MessageNo,Information,Number** 
1000,1,a,2
99,2,bs,3
1000,3,g,4
66,2,a,3
20,16,3,b
1000,7,c,4
99,1,lz,4 
...

Я должен заказать этот файл по CallId и MessageNo как asc. (Один из способов-загрузить базу данных - >сортировка - >экспорт)

Как я могу отсортировать этот файл без загрузки всех строк в памяти в C#? (как строка за строкой с помощью streamreader)

знаете ли вы библиотеку для решения проблемы? я жду твоего совета., спасибо

3 ответов


вы должны использовать команды сортировки ОС. Обычно это просто

sort myfile

затем некоторые мистические переключатели. Эти команды обычно хорошо работают с большими файлами, и часто есть опции для указания временного хранения на других физических жестких дисках. Смотрите это предыдущий вопрос, и окна sort команда "человек" страницы. Поскольку сортировки Windows недостаточно для вашей конкретной проблемы сортировки, вы можете использовать GNU coreutils которые приносят силу linux sort в Windows.

решение

вот что вам нужно сделать.

  1. скачать GNU Coreutils двоичные файлы ZIP и экстракт sort.exe из папки bin в некоторую папку на вашем компьютере, например папку, в которой находится ваш файл для сортировки.
  2. скачать зависимости GNU Coreutils ZIP и выбрать .dll файлы в ту же папку, sort.exe

теперь предположим, что ваш файл выглядит так:

1000,1,a,2
99,2,bs,3
1000,3,g,4
66,2,a,3
20,16,3,b
1000,7,c,4
99,1,lz,4 

вы можете написать в командной строке:

sort.exe yourfile.csv -t, -g

что бы выход:

20,16,3,b
66,2,a,3
99,1,lz,4
99,2,bs,3
1000,1,a,2
1000,3,g,4
1000,7,c,4

посмотреть дополнительные параметры команды здесь. Если это то, что вы хотите, не забудьте указать выходной файл с -o переключатель, вот так:

sort.exe yourfile.csv -t, -g -o sorted.csv

Это классическая задача алгоритма называется Внешняя Сортировка.

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

С .NET Framework точки зрения я бы рекомендовал использовать .NET 4 функции - Сопоставленные С Памятью Файлы для проецирования частей файла в памяти в виде отдельных представлений.

здесь пример Java внешней сортировки слияния, вы должны быть в состоянии принять его на C# легко:

EDIT: добавлен пример использования упомянутый образец Java, чтобы продемонстрировать свою простоту

Comparator<String> comparator = new Comparator<String>() 
{                         
  public int compare(String r1, String r2)
  {                                 
     return r1.compareTo(r2);
  }
};                 

List<File> l = sortInBatch(new File(inputfile), comparator);                
mergeSortedFiles(l, new File(outputfile), comparator); 

вы должны использовать python для такого рода задач:)

посмотрите здесь аналогичный, полный рабочий пример:

Python: как читать огромный текстовый файл в память

EDIT:

в этом же ответе есть ссылка, полезная в случае, если ваш файл действительно больше, чем доступный объем ОЗУ:http://code.activestate.com/recipes/466302/