我在form1构造函数中调用了两个方法:
DirSearch(@"D:\C-Sharp");
SearchInFiles();
DirSearch方法:
public static void DirSearch(string sDir)
{
try
{
foreach (string d in Directory.GetDirectories(sDir))
{
foreach (string f in Directory.GetFiles(d))
{
files.Add(f);
}
DirSearch(d);
}
}
catch (System.Exception excpt)
{
Console.WriteLine(excpt.Message);
}
}
SearchInfiles方法:
private void SearchInFiles()
{
for (int i = 0; i < files.Count; i++)
{
string[] lines = File.ReadAllLines(files[i]);
for (int x = 0; x < lines.Length; x++)
{
if (lines[x].Contains("setting"))
{
filesContent.Add(lines[x]);
}
}
}
}
我在线上没有内存异常:
string[] lines = File.ReadAllLines(files[i]);
如果可能的话,如何更快地进行搜索?如何避免此异常?
也许我需要以某种方式使它不会在dll文件和其他不可编辑的文件中搜索例如* .cs和* .txt这样的文件我该怎么办?
答案 0 :(得分:6)
如果可能的话,如何更快地进行搜索?如何避免此异常?
该行:
string[] lines = File.ReadAllLines(files[i]);
&#34;它在锡上的含义&#34; - 它从整个文件(在内存中)读取每一行。对于非常大的文件,这将占用大量内存。
避免这种情况的方法是不一次将所有行加载到内存中,而是逐行将文件流入内存。
using(var streamReader sr = new StreamReader(files[i]))
{
string line;
while((line = sr.ReadLine()) != null)
{
if (line.Contains("setting"))
{
filesContent.Add(line);
}
}
}
请注意,如果使用.NET 4或更高版本,使用File.ReadLines
foreach(var line in File.ReadLines(files[i]))
{
....
}
提供searchPattern来完成该部分也许我需要以某种方式使它不会在dll文件和其他不可编辑的文件中搜索例如* .cs和* .txt这样的文件我该怎么办?
foreach (string f in Directory.GetFiles(d,"*.txt"))
....
似乎没有办法提供多个文件扩展名,但您可以简单地将2个列表链接在一起
// all txt or cs files
var files = Directory.GetFiles(d,"*.txt").Concat(Directory.GetFiles(d,"*.cs"));
foreach(var f in files)
....
答案 1 :(得分:3)
A)不是先获取所有文件然后再处理所有文件,而是在找到文件后立即处理。
因此,不要使用DirSearch中的files.Add
,而是使用您找到的参数调用SearchInFile。
B)不要读取文件中的所有行(它们是文本文件,不是吗?),但是使用File.ReadLines
来处理该行读,所以你可以忘记它,如果它不匹配。
foreach(string line in File.ReadLines(theFile))
{
// test the "line"
}
答案 2 :(得分:3)
您不仅要一次读入内存中的所有行,而且还要查看目录中存在的每个文件。
这可能是个问题。例如,如果其中一个文件是某个大于2演出的数据文件怎么办?那你就会有记忆问题。
当您在文件列表中添加文件时,还要检查以确保文件属于您想要的类型。
例如。
foreach (string f in Directory.GetFiles(d))
{
if(f.Contains(".txt") || f.Contains(".cs"))
files.Add(f);
}
答案 3 :(得分:2)
为什么要将所有名字列入清单?它必须在开始处理第一个列表之前读取整个列表。
为什么在处理前阅读所有行?
public List<string> FindLines(string DirName)
{
List<string> findLines = new List<string>();
DirectoryInfo di = new DirectoryInfo(DirName);
if(di != null && di.Exists)
{
foreach(FileInfo fi in di.EnumerateFiles("*", SearchOption.AllDirectories))
{
//Debug.WriteLine(fi.Extension);
//Debug.WriteLine(fi.FullName);
if ( string.Compare(fi.Extension, ".cs", true) == 0
|| string.Compare(fi.Extension, ".txt", true) == 0
|| string.Compare(fi.Extension, ".text", true) == 0)
{
//findLines.Add(fi.FullName);
using (StreamReader sr = fi.OpenText())
{
string s = "";
while ((s = sr.ReadLine()) != null)
{
if (s.Contains("setting"))
findLines.Add(s);
}
}
}
}
}
return findLines;
}
答案 4 :(得分:1)
您的问题是一次性将所有行读入内存。
您应该使用流来读取文件,或者一次读取一行。