我必须合并数千个大文件(每个大约200MB)。我想知道合并这些文件的最佳方法是什么。行将有条件地复制到合并文件。可以使用File.AppendAllLines或使用Stream.CopyTo吗?
使用File.AppendAllLines
for (int i = 0; i < countryFiles.Length; i++){
string srcFileName = countryFiles[i];
string[] countryExtractLines = File.ReadAllLines(srcFileName);
File.AppendAllLines(actualMergedFileName, countryExtractLines);
}
使用Stream.CopyTo
using (Stream destStream = File.OpenWrite(actualMergedFileName)){
foreach (string srcFileName in countryFiles){
using (Stream srcStream = File.OpenRead(srcFileName)){
srcStream.CopyTo(destStream);
}
}
}
答案 0 :(得分:3)
sab669的答案是正确的,你想使用StreamReader然后循环遍历文件的每一行...... 我建议单独编写每个文件,否则你将很快用尽许多200mb文件
例如:
foreach(File f in files)
{
List<String> lines = new List<String>();
string line;
int cnt = 0;
using(StreamReader reader = new StreamReader(f)) {
while((line = reader.ReadLine()) != null) {
// TODO : Put your conditions in here
lines.Add(line);
cnt++;
}
}
f.Close();
// TODO : Append your lines here using StreamWriter
}
答案 1 :(得分:3)
您可以一个接一个地编写文件。例如:
static void MergingFiles(string outputFile, params string[] inputTxtDocs)
{
using (Stream outputStream = File.OpenWrite(outputFile))
{
foreach (string inputFile in inputTxtDocs)
{
using (Stream inputStream = File.OpenRead(inputFile))
{
inputStream.CopyTo(outputStream);
}
}
}
}
在我看来,上面的代码实际上是高性能的,因为Stream.CopyTo()具有非常简单的算法,因此该方法非常有效。反射器使其核心如下:
private void InternalCopyTo(Stream destination, int bufferSize)
{
int num;
byte[] buffer = new byte[bufferSize];
while ((num = this.Read(buffer, 0, buffer.Length)) != 0)
{
destination.Write(buffer, 0, num);
}
}
答案 2 :(得分:2)
假设您有一个条件必须为true(即谓词),以便将一个文件中的每一行添加到另一个文件中。
您可以按如下方式有效地处理:
var filteredLines =
File.ReadLines("MySourceFileName")
.Where(line => line.Contains("Target")); // Put your own condition here.
File.AppendAllLines("MyDestinationFileName", filteredLines);
此方法可扩展到多个文件,并避免将整个文件加载到内存中。
如果不是将所有行追加到文件中,而是想要替换内容,那么你可以这样做:
File.WriteAllLines("MyDestinationFileName", filteredLines);
而不是
File.AppendAllLines("MyDestinationFileName", filteredLines);
另请注意,如果您不使用UTF8,这些方法的重载允许您指定编码。
最后,不要被不一致的方法命名抛出。File.ReadLines()
不会将所有行读入内存,但File.ReadAllLines()
会这样做。但是,File.WriteAllLines()
不会将所有行缓冲到内存中,或者期望它们全部缓冲在内存中;它使用IEnumerable<string>
作为输入。