Как я могу отсортировать большой CSV-файл без загрузки в память - PullRequest
10 голосов
/ 09 сентября 2011

У меня есть 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 #?(например, строка за строкой, используя потоковый ридер)

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

Ответы [ 3 ]

6 голосов
/ 09 сентября 2011

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

sort myfile

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

Решение

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

  1. Загрузите GNU Coreutils Binaries 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
3 голосов
/ 09 сентября 2011

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

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

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

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

РЕДАКТИРОВАТЬ: Добавлен пример использования упомянутого примера 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); 
0 голосов
/ 09 сентября 2011

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

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

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

РЕДАКТИРОВАТЬ:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...