【发布时间】:2014-07-19 05:01:52
【问题描述】:
我有 2 个 csv 文件,file1.csv 和 file2.csv。每个文件中的某些行将是相同的。我希望创建一个基于 file2.csv 的第三个 csv 文件,但从中删除 file1.csv 中存在的任何行。实际上,我希望从 file2.csv 中减去 file1.csv,忽略 file1 中存在但不在 file2 中的任何行。 我知道我可以使用streamreader 读取file2.csv 中的每一行并在file1.csv 中搜索它。如果它在 file1.csv 中不存在,我可以将其写入 file3.csv。但是,这些文件非常大(超过 30000 行),我相信这将花费大量的处理时间。 我怀疑可能有更好的方法将每个 csv 加载到数组中,然后对它们执行简单的减法函数以获得所需的结果。我将不胜感激有关代码或解决此问题的方法的一些帮助。
文件内容示例:
file1.csv
dt97861.jpg,149954,c1714ee1,\folder1\folderA\,
dt97862.jpg,149955,c1714ee0,\folder1\folderA\,
dt97863.jpg,59368,cd23f223,\folder2\folderA\,
dt97864.jpg,57881,0835be4a,\folder2\folderB\,
dt97865.jpg,57882,0835be4b,\folder2\folderB\,
file2.csv
dt97862.jpg,149955,c1714ee0,\folder1\folderA\,
dt97863.jpg,59368,cd23f223,\folder2\folderA\,
dt97864.jpg,57881,0835be4a,\folder2\folderB\,
dt97865.jpg,57882,0835be4b,\folder2\folderB\,
dt97866.jpg,57883,0835be4c,\folder2\folderB\,
dt97867.jpg,57884,0835be4d,\folder3\folderA\,
dt97868.jpg,57885,0835be4e,\folder3\folderA\,
我需要的结果是:
file3.csv
dt97866.jpg,57883,0835be4c,\folder2\folderB\,
dt97867.jpg,57884,0835be4d,\folder3\folderA\,
dt97868.jpg,57885,0835be4e,\folder3\folderA\,
编辑: 在下面的帮助下,我得出了以下我认为不错且优雅的解决方案:
public static IEnumerable<string> ReadFile(string path)
{
string line;
using (var reader = File.OpenText(path))
while ((line = reader.ReadLine()) != null)
yield return line;
}
然后:
var file2 = ReadFile(file2FilePath);
var file1 = ReadFile(file1FilePath);
var file3 = file2.Except(file1);
File.WriteAllLines(file3FilePath, file3);
【问题讨论】:
-
你应该展示你尝试过的东西。
-
我通常会,但在这种情况下,我不确定该采取什么方法。我已经描述了一种我认为可行的方法,但我希望有人会提出更有效的建议。
-
两个 CSV 文件是否已按字母顺序排列? (看起来是这样。)如果不是,输出的顺序重要吗? 30,000 行长度约 50 个字符只有几兆字节,所以我建议将两个文件都拉入、排序并使用二进制搜索搜索重复项。
-
我会使用 EPPlus 之类的东西,将两个文件都加载到内存集合中(如果文件不是那么大)。然后你可以使用一些 LINQ 或其他东西来解析不在文件 1 中的行。
-
如果两个文件的排序方式始终相同,您可以使用external merge。