C# 如何检查文件中字符串的一部分?
我正在尝试编写一个代码,该代码将检查给定目录和子目录下的所有文件,以查找从网页传递的字符串。到目前为止,我有以下代码:C# 如何检查文件中字符串的一部分?,c#,C#,我正在尝试编写一个代码,该代码将检查给定目录和子目录下的所有文件,以查找从网页传递的字符串。到目前为止,我有以下代码: private void ProcessDirectory(string targetDirectory, string origDirectory, string ObjectName) { string[] fileEntries = Directory.GetFiles(targetDirectory); string[]
private void ProcessDirectory(string targetDirectory, string origDirectory, string ObjectName)
{
string[] fileEntries = Directory.GetFiles(targetDirectory);
string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach (string fileName in fileEntries)
{
ProcessFile(fileName, origDirectory, ObjectName);
}
foreach (string subdirectory in subdirectoryEntries)
ProcessDirectory(subdirectory, origDirectory, ObjectName);
}
private void ProcessFile(string path, string origDirectory, string ObjectName)
{
if (ObjectName != "")
{
var fileLines = File.ReadAllLines(path);
List<string> fileItems = new List<string>(fileLines);
if (fileItems.Contains(ObjectName))
{
string sExt = Path.GetExtension(path).ToLower();
if (sExt == ".txt")
{
listTextFiles.Items.Add(path.Replace(origDirectory, ""));
}
}
}
private void ProcessDirectory(字符串targetDirectory、字符串origDirectory、字符串ObjectName)
{
字符串[]fileEntries=Directory.GetFiles(targetDirectory);
string[]subdirectory entries=Directory.GetDirectories(targetDirectory);
foreach(文件项中的字符串文件名)
{
ProcessFile(文件名、源目录、对象名);
}
foreach(子目录入口中的字符串子目录)
ProcessDirectory(子目录、origDirectory、ObjectName);
}
私有void进程文件(字符串路径、字符串源目录、字符串对象名)
{
if(ObjectName!=“”)
{
var fileLines=File.ReadAllLines(路径);
列表文件项=新列表(文件行);
if(fileItems.Contains(ObjectName))
{
字符串sExt=Path.GetExtension(Path.ToLower();
如果(sExt==“.txt”)
{
listextfiles.Items.Add(path.Replace(origDirectory)(“”));
}
}
}
它可以工作,但问题是它只在文件中查找一个完整的单词。例如,如果我查找单词“Account”,并且文件包含单词“Account”,我的代码将工作。如果文件包含单词“AccountCode”,我的搜索将找不到它。是否有方法修复它
另一个问题是,如何添加一个计数器,在进程结束时显示在给定目录和所有子目录下检查了多少文件。
如果fileItems.Contains(ObjectName))
将搜索列表fileItems
,条件是:如果该列表包含的项等于ObjectName
您可能想要:如果该列表包含包含ObjectName
的项,则更改为:
if (fileItems.Any(e => e.Contains(ObjectName)))
if fileItems.Contains(ObjectName))
将在以下条件下搜索列表fileItems
:如果该列表包含的项等于ObjectName
您可能想要:如果该列表包含包含ObjectName
的项,则更改为:
if (fileItems.Any(e => e.Contains(ObjectName)))
这是一种非常迂回的方法。只需加载整个文件内容并使用
IndexOf
:
var content = File.ReadAllText(path);
if (content.IndexOf(ObjectName) > -1) {
// rest of your code here
}
不需要逐行加载,用这些行初始化一个全新的列表,然后检查每一行
正如您所要求的,这还提供了部分搜索的好处
<>你可以通过仔细检查你消耗的内存量来极大地提高这一点。你的方法和我这里提供的内存都可能分配大的内存块,只有在条件检查之后才是无用的。考虑使用<代码> StringBuilder < /代码>并重新使用每个文件。 < P>这是一个可怕的问题。大概是这样做的。只需加载整个文件内容并使用
IndexOf
:
var content = File.ReadAllText(path);
if (content.IndexOf(ObjectName) > -1) {
// rest of your code here
}
不需要逐行加载,用这些行初始化一个全新的列表,然后检查每一行
正如您所要求的,这还提供了部分搜索的好处
<>你可以通过仔细检查你消耗了多少内存来极大地提高这一点。你的方法和我这里提供的内存都可能分配大的内存块,只有在条件检查后才是无用的。考虑使用<代码> StringBuilder < /代码>并重新使用每个文件。 回答SECON因为您在这里使用递归,所以您需要声明一个属性或类级别变量,并在ProcessFile方法中递增它,例如:
public int NumberOfMatches { get; set; }
ProcessFile...
{
if (fileItems.Contains(ObjectName))
{
NumberOfMatches++;
}
作为补充说明,这里没有理由使用递归,您只需通过一次调用即可获得所有文件:
string[] allFiles = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
如果性能是一个问题,你也可以考虑多线程处理:
Parallel.ForEach(allFiles,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
allFiles =>
{
...
}
回答第二个问题。因为在这里使用递归,所以需要声明属性或类级别变量,并在ProcessFile方法中递增它,例如:
public int NumberOfMatches { get; set; }
ProcessFile...
{
if (fileItems.Contains(ObjectName))
{
NumberOfMatches++;
}
作为补充说明,这里没有理由使用递归,您只需通过一次调用即可获得所有文件:
string[] allFiles = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
如果性能是一个问题,你也可以考虑多线程处理:
Parallel.ForEach(allFiles,
new ParallelOptions { MaxDegreeOfParallelism = 4 },
allFiles =>
{
...
}
当检查字符串的内容时,不要忘记为字符串实现一个比较器
If(string.Contains( value ,StringComparer.CurrentCultureIgnoreCase ))
// Apply logic...
在检查字符串内容时,通常会忽略它…请不要忘记为字符串实现一个比较器
If(string.Contains( value ,StringComparer.CurrentCultureIgnoreCase ))
// Apply logic...
它经常被忽略…对于“非常大”的文件,在流(甚至可能是一行IEnumerable)上执行操作可能是有意义的…但这确实是一个非常简单(而且可能足够)的方法。@user2864740确实如此。从内存占用的角度来看,重新使用流或StringBuilder会更有效率。对于“非常大”文件在流(甚至可能是IEnumerable行)上执行操作可能有意义……但这确实是一个非常简单(而且可能足够)的方法。@user2864740确实如此。就内存占用而言,重新使用的流或StringBuilder将更有效率。