first commit

This commit is contained in:
Tomato 2026-01-09 13:25:44 +08:00
commit a86b7f2e8a
4 changed files with 321 additions and 0 deletions

View 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
View 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
View 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

Binary file not shown.