我负责开发一个在生产服务器上运行的应用程序,它的目的是搜索和替换每个ini, xml和配置文件扩展名中的一些特定字符串,我必须关心性能(总共150台服务器)。更换之前,我必须备份文件。实现这一目标的最佳方式是什么?顺便说一句,我可以使用Dot Net 4.0,但最好使用3.5,因为不是每个服务器都有4.0,但如果有明显的优势,我可以升级到4.0。现在我是这样想的:
String[] arrayFiles = Directory.GetFiles(strFylesystem , strExtensao, SearchOption.AllDirectories);
foreach (string s in arrayFiles ){
File.Copy(pathOrigin + s, pathNew);
searchFound = false;
foreach (string line in File.ReadAllLines(pathNew + s){
if (line.contains("string_searched")){
line.Replace("string_searched", new_string);
searchFound = true;
}
if (!searchFound){
File.Delete(pathNew + s);
}
}
}
我发现一些论坛使用Lambda, PLINQ和正则表达式。除了个人偏好,这些对我的表现有帮助吗?例如:如果不使用File.ReadAllLines
而使用StreamReader
开发,性能会更好吗?有没有办法从窗口包装findStr
并获得性能改进?
您的限制因素将是磁盘访问速度,并且您可以做的事情不多。当然,使用Lambda表达式不会对性能产生影响。
并行搜索没有帮助,除非你有多个驱动器。也就是说,让两个线程在同一个驱动器上的不同目录上工作可能会减慢速度,因为它们会争夺磁盘访问权。
一个潜在的问题是,当您枚举驱动器上的所有文件时,您正在驱动器上创建新文件。如果你不小心,你可能会进入一个无限循环。也就是说,读取x.xml,创建一个新文件x.new.xml,然后找到x.new.xml,修改它,等等。您最好扫描整个驱动器,并创建一个想要更改的文件列表。然后浏览列表,进行更改。
我建议你不要在c#中这样做。相反,编写两个PowerShell脚本。第一个在驱动器中搜索符合条件的文件,并将这些文件名写入文件。第二个程序从该文件中读取文件名,并处理这些文件。参见https://stackoverflow.com/a/60065/56778查看示例。
这可能不会像c#程序那么快,但我怀疑它会慢很多。同样,限制因素是磁盘访问速度,而不是处理速度。而你的开发时间也只需要几个小时,而不是几天。而且修改PowerShell脚本要比修改c#程序容易得多。