Как сортировать большой 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.
решение
вот что вам нужно сделать.
- скачать GNU Coreutils двоичные файлы ZIP и экстракт
sort.exe
из папки bin в некоторую папку на вашем компьютере, например папку, в которой находится ваш файл для сортировки. - скачать зависимости 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/