7 changed files with 123 additions and 6 deletions
@ -0,0 +1,93 @@
@@ -0,0 +1,93 @@
|
||||
import 'dart:io'; |
||||
import 'dart:collection'; |
||||
|
||||
Future<Map<String, int>> searchInFiles({ |
||||
required String folderPath, |
||||
required String filePattern, |
||||
required List<String> searchTerms, |
||||
required bool caseSensitive, |
||||
required bool wholeWord, |
||||
}) async { |
||||
// 初始化结果映射,默认所有搜索词出现0次 |
||||
final result = HashMap<String, int>( |
||||
equals: caseSensitive ? null : (a, b) => a.toLowerCase() == b.toLowerCase(), |
||||
hashCode: caseSensitive ? null : (s) => s.toLowerCase().hashCode, |
||||
); |
||||
|
||||
for (final term in searchTerms) { |
||||
result[term] = 0; |
||||
} |
||||
|
||||
// 获取文件夹下所有匹配的文件 |
||||
final dir = Directory(folderPath); |
||||
if (!await dir.exists()) { |
||||
throw ArgumentError('Directory does not exist: $folderPath'); |
||||
} |
||||
|
||||
final files = await dir.list() |
||||
.where((entity) => entity is File) |
||||
.cast<File>() |
||||
.where((file) => _matchesPattern(file.path, filePattern)) |
||||
.toList(); |
||||
|
||||
// 为每个搜索词构建正则表达式 |
||||
final regexMap = <String, RegExp>{}; |
||||
for (final term in searchTerms) { |
||||
final pattern = wholeWord |
||||
? r'(?<!\w)' + RegExp.escape(term) + r'(?!\w)' |
||||
: term; |
||||
|
||||
regexMap[term] = RegExp( |
||||
pattern, |
||||
caseSensitive: caseSensitive, |
||||
); |
||||
} |
||||
|
||||
// 并行处理文件 |
||||
await Future.wait(files.map((file) async { |
||||
try { |
||||
final content = await file.readAsString(); |
||||
|
||||
for (final term in searchTerms) { |
||||
final regex = regexMap[term]!; |
||||
final matches = regex.allMatches(content); |
||||
result[term] = result[term]! + matches.length; |
||||
} |
||||
} catch (e) { |
||||
print('Error reading file ${file.path}: $e'); |
||||
} |
||||
})); |
||||
|
||||
// 移除匹配次数为0的项 |
||||
result.removeWhere((_, count) => count == 0); |
||||
|
||||
return result; |
||||
} |
||||
|
||||
bool _matchesPattern(String fileName, String pattern) { |
||||
// 简单的通配符匹配实现(支持 *.txt 这样的简单模式) |
||||
if (pattern == '*') return true; |
||||
if (pattern.startsWith('*.')) { |
||||
final ext = pattern.substring(1); |
||||
return fileName.toLowerCase().endsWith(ext.toLowerCase()); |
||||
} |
||||
// 更复杂的模式可以在这里扩展 |
||||
return RegExp(pattern.replaceAll('.', r'\.').replaceAll('*', '.*'), |
||||
caseSensitive: false).hasMatch(fileName); |
||||
} |
||||
|
||||
// 使用示例 |
||||
void main() async { |
||||
final result = await searchInFiles( |
||||
folderPath: '/path/to/your/folder', |
||||
filePattern: '*.txt', // 或者 '*.dart' 等 |
||||
searchTerms: ['Flutter', 'Dart', 'widget', 'main'], |
||||
caseSensitive: false, |
||||
wholeWord: true, |
||||
); |
||||
|
||||
print('Search results:'); |
||||
result.forEach((term, count) { |
||||
print('$term: $count'); |
||||
}); |
||||
} |
Loading…
Reference in new issue