我有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逐行)
你知道一个解决方案库吗? 我等你的意见, 感谢
答案 0 :(得分:6)
您应该使用OS排序命令。通常它只是
sort myfile
接着是一些神秘的开关。这些命令通常适用于大型文件,并且通常有选项可在其他物理硬盘上指定临时存储。请参阅此previous question和Windows sort
命令"man" page。由于Windows排序不足以满足您的特定排序问题,因此您可能希望使用GNU coreutils将Linux sort
的强大功能带到Windows。
这是你需要做的。
sort.exe
解压缩到计算机上的某个文件夹,例如您要排序的文件所在的文件夹。.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
见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/