first commit
This commit is contained in:
commit
a86b7f2e8a
63
file_matcher/file_matcher.v
Normal file
63
file_matcher/file_matcher.v
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// file_matcher.v
|
||||||
|
module file_matcher
|
||||||
|
|
||||||
|
// 匹配模式枚举
|
||||||
|
pub enum MatchMode {
|
||||||
|
exact // 精确匹配
|
||||||
|
wildcard // 通配符匹配 (* 和 _)
|
||||||
|
like // 模糊匹配,忽略大小写
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通配符匹配函数
|
||||||
|
fn wildcard_match(pattern string, name string) bool {
|
||||||
|
mut i := 0
|
||||||
|
mut j := 0
|
||||||
|
mut star_idx := -1
|
||||||
|
mut match_idx := -1
|
||||||
|
|
||||||
|
for i < name.len {
|
||||||
|
if j < pattern.len && (pattern[j] == name[i] || pattern[j] == `_`) {
|
||||||
|
i++
|
||||||
|
j++
|
||||||
|
} else if j < pattern.len && pattern[j] == `*` {
|
||||||
|
star_idx = j
|
||||||
|
match_idx = i
|
||||||
|
j++
|
||||||
|
} else if star_idx != -1 {
|
||||||
|
j = star_idx + 1
|
||||||
|
match_idx++
|
||||||
|
i = match_idx
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理模式末尾的 *
|
||||||
|
for j < pattern.len && pattern[j] == `*` {
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
|
||||||
|
return j == pattern.len
|
||||||
|
}
|
||||||
|
|
||||||
|
// 主匹配函数
|
||||||
|
pub fn match_file(pattern string, filename string, mode MatchMode) bool {
|
||||||
|
match mode {
|
||||||
|
.exact {
|
||||||
|
return filename == pattern
|
||||||
|
}
|
||||||
|
.wildcard {
|
||||||
|
return wildcard_match(pattern, filename)
|
||||||
|
}
|
||||||
|
.like {
|
||||||
|
// 移除%符号,进行模糊匹配
|
||||||
|
clean_pattern := pattern.replace('%', '')
|
||||||
|
return filename.to_lower().contains(clean_pattern.to_lower())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否为通配符模式
|
||||||
|
pub fn is_wildcard_pattern(pattern string) bool {
|
||||||
|
return pattern.contains('*') || pattern.contains('_')
|
||||||
|
}
|
||||||
176
main.v
Normal file
176
main.v
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
// main.v
|
||||||
|
module main
|
||||||
|
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import file_matcher
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// 直接读取目录
|
||||||
|
mut current_dir := '.'
|
||||||
|
print('请输入要搜索的目录 (默认为当前目录): ')
|
||||||
|
mut input := os.get_line()
|
||||||
|
if input.trim_space() != '' {
|
||||||
|
current_dir = input
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取搜索模式
|
||||||
|
mut search_pattern := '*'
|
||||||
|
print('请输入搜索模式 (* 显示所有文件): ')
|
||||||
|
input = os.get_line()
|
||||||
|
if input.trim_space() != '' {
|
||||||
|
search_pattern = input
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证目录
|
||||||
|
if !os.is_dir(current_dir) {
|
||||||
|
println('错误: 目录 "$current_dir" 不存在!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
println('')
|
||||||
|
println('搜索目录: $current_dir')
|
||||||
|
println('搜索模式: $search_pattern')
|
||||||
|
println('开始搜索...')
|
||||||
|
println('')
|
||||||
|
|
||||||
|
mut scanner := new_scanner(12)
|
||||||
|
scanner.do_scan_with_search(current_dir, search_pattern)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 原始Scanner结构体
|
||||||
|
struct Scanner {
|
||||||
|
mut:
|
||||||
|
max_worker int = 32
|
||||||
|
worker_count int
|
||||||
|
search_request chan string
|
||||||
|
work_done chan bool
|
||||||
|
|
||||||
|
// 搜索相关字段
|
||||||
|
search_pattern string
|
||||||
|
search_mode file_matcher.MatchMode
|
||||||
|
match_count int
|
||||||
|
search_active bool
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_scanner(max_worker_count int) &Scanner {
|
||||||
|
return &Scanner{
|
||||||
|
max_worker: max_worker_count
|
||||||
|
search_request: chan string{cap: 100}
|
||||||
|
work_done: chan bool{cap: 100}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置搜索条件
|
||||||
|
fn (mut s Scanner) set_search(pattern string, mode file_matcher.MatchMode) {
|
||||||
|
s.search_pattern = pattern
|
||||||
|
s.search_mode = mode
|
||||||
|
s.search_active = pattern != '' && pattern != '*'
|
||||||
|
s.match_count = 0
|
||||||
|
println('设置搜索: 模式=$pattern, 类型=$mode, 激活=$s.search_active')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 增强的扫描函数,支持文件过滤
|
||||||
|
fn (mut s Scanner) scanner_with_filter(path string, is_master bool) {
|
||||||
|
items := os.ls(path) or {
|
||||||
|
// 只在路径不是系统目录时显示错误
|
||||||
|
if !path.contains('System Volume Information') &&
|
||||||
|
!path.contains('\$RECYCLE.BIN') &&
|
||||||
|
!path.contains('Windows') {
|
||||||
|
println('注意: 无法访问目录 "$path"')
|
||||||
|
}
|
||||||
|
if is_master {
|
||||||
|
s.work_done <- true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for item in items {
|
||||||
|
full_path := os.join_path(path, item)
|
||||||
|
|
||||||
|
if os.is_dir(full_path) {
|
||||||
|
if s.worker_count < s.max_worker {
|
||||||
|
s.search_request <- full_path
|
||||||
|
} else {
|
||||||
|
s.scanner_with_filter(full_path, false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果没有激活搜索,或者文件匹配模式,则输出
|
||||||
|
if !s.search_active {
|
||||||
|
println('$full_path')
|
||||||
|
s.match_count++
|
||||||
|
} else {
|
||||||
|
if file_matcher.match_file(s.search_pattern, item, s.search_mode) {
|
||||||
|
println('$full_path')
|
||||||
|
s.match_count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if is_master {
|
||||||
|
s.work_done <- true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行扫描(可选择是否搜索)
|
||||||
|
fn (mut s Scanner) do_scan_with_search(path string, search_pattern string) {
|
||||||
|
start := time.now()
|
||||||
|
|
||||||
|
// 设置搜索条件(如果提供了搜索模式)
|
||||||
|
if search_pattern != '' {
|
||||||
|
// 自动检测搜索模式
|
||||||
|
mut mode := file_matcher.MatchMode.exact
|
||||||
|
|
||||||
|
if search_pattern == '*' {
|
||||||
|
// 显示所有文件,不激活搜索
|
||||||
|
mode = .exact
|
||||||
|
s.search_active = false
|
||||||
|
s.search_pattern = ''
|
||||||
|
} else if file_matcher.is_wildcard_pattern(search_pattern) {
|
||||||
|
mode = .wildcard
|
||||||
|
} else if search_pattern.contains('%') {
|
||||||
|
mode = .like
|
||||||
|
}
|
||||||
|
|
||||||
|
s.set_search(search_pattern, mode)
|
||||||
|
println('搜索模式: $search_pattern (${mode})')
|
||||||
|
} else {
|
||||||
|
s.search_active = false
|
||||||
|
s.search_pattern = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
s.worker_count = 1
|
||||||
|
s.match_count = 0
|
||||||
|
go s.scanner_with_filter(path, true)
|
||||||
|
s.watting_for_workers()
|
||||||
|
|
||||||
|
end := time.now()
|
||||||
|
duration := end - start
|
||||||
|
|
||||||
|
println('')
|
||||||
|
if s.search_active {
|
||||||
|
println('找到 ${s.match_count} 个匹配文件')
|
||||||
|
} else {
|
||||||
|
println('找到 ${s.match_count} 个文件')
|
||||||
|
}
|
||||||
|
println('耗时: ${duration.seconds()} 秒')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待工作线程完成
|
||||||
|
fn (mut s Scanner) watting_for_workers() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
path := <- s.search_request {
|
||||||
|
s.worker_count++
|
||||||
|
go s.scanner_with_filter(path, true)
|
||||||
|
}
|
||||||
|
_ := <- s.work_done {
|
||||||
|
s.worker_count--
|
||||||
|
if s.worker_count == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
82
main.v.bk
Normal file
82
main.v.bk
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
|
||||||
|
module main
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
current_dir := 'C:\\'
|
||||||
|
mut scanner :=new_scanner(12)
|
||||||
|
scanner.do_scan(current_dir)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn new_scanner(max_worker_count int) &Scanner{
|
||||||
|
return &Scanner{
|
||||||
|
max_worker: max_worker_count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct Scanner{
|
||||||
|
mut:
|
||||||
|
max_worker int = 32
|
||||||
|
worker_count int
|
||||||
|
search_request chan string
|
||||||
|
work_done chan bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn (mut s Scanner)scanner(path string,is_master bool){
|
||||||
|
items := os.ls(path) or {
|
||||||
|
println('列出目录失败: $err\n$path')
|
||||||
|
s.work_done <- true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for item in items {
|
||||||
|
full_path := os.join_path(path, item)
|
||||||
|
if os.is_dir(full_path) {
|
||||||
|
if s.worker_count < s.max_worker{
|
||||||
|
s.search_request <- full_path
|
||||||
|
}else{
|
||||||
|
s.scanner(full_path,false)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println('$full_path')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if is_master{
|
||||||
|
s.work_done <- true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn (mut s Scanner)do_scan(path string){
|
||||||
|
start := time.now()
|
||||||
|
|
||||||
|
s.worker_count = 1
|
||||||
|
go s.scanner(path,true)
|
||||||
|
s.watting_for_workers()
|
||||||
|
|
||||||
|
end := time.now()
|
||||||
|
duration := end - start
|
||||||
|
println('耗时: ${duration.seconds()} 秒')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn (mut s Scanner)watting_for_workers(){
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
path := <- s.search_request {
|
||||||
|
s.worker_count++
|
||||||
|
go s.scanner(path,true)
|
||||||
|
}
|
||||||
|
_ :=<- s.work_done{
|
||||||
|
s.worker_count--
|
||||||
|
if s.worker_count == 0{
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
scanner.exe
Normal file
BIN
scanner.exe
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user