如何在不加载到内存的情况下对大型csv文件进行排序

时间:2011-09-09 11:39:13

标签: c# file sorting 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。 (一种方法是加载数据库 - > sort-> export)

如何在不将所有行加载到c#内存的情况下对此文件进行排序? (比如使用streamreader逐行)

你知道一个解决方案库吗? 我等你的意见, 感谢

3 个答案:

答案 0 :(得分:6)

您应该使用OS排序命令。通常它只是

sort myfile

接着是一些神秘的开关。这些命令通常适用于大型文件,并且通常有选项可在其他物理硬盘上指定临时存储。请参阅此previous question和Windows sort命令"man" page。由于Windows排序不足以满足您的特定排序问题,因此您可能希望使用GNU coreutils将Linux sort的强大功能带到Windows。

解决方案

这是你需要做的。

  1. 从bin文件夹下载GNU Coreutils Binaries ZIP并将sort.exe解压缩到计算机上的某个文件夹,例如您要排序的文件所在的文件夹。
  2. 下载GNU Coreutils Dependencies ZIP并将.dll个文件解压缩到与sort.exe相同的文件夹
  3. 现在假设你的文件是这样的:

    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
    

    more command options here。如果这是您想要的,请不要忘记提供带-o开关的输出文件,如下所示:

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

答案 1 :(得分:3)

这是一个名为External Sorting的经典算法问题。

  

当排序的数据不适合时,需要进行外部排序   进入计算设备(通常是RAM)的主存储器而不是   它们必须驻留在较慢的外部存储器(通常是硬盘驱动器)中。   外部排序通常使用排序合并策略。在排序中   阶段,读取小到足以适合主存储器的数据块,   排序并写出临时文件。在合并阶段,   已排序的子文件合并为一个较大的文件

.NET Framework的角度来看,我建议利用.NET 4功能 - Memory Mapped Files将内存中的部分文件投影为单独的视图。

Here is外部合并排序的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); 

答案 2 :(得分:-2)

你应该使用python来完成这类任务:)

在这里查看一个类似的,完整的工作示例:

Python: How to read huge text file into memory

修改

在同一个答案中,如果你的文件真的比RAM的可用量大,那么有一个链接很有用:http://code.activestate.com/recipes/466302/