Golang批量删除文件工具:如何替代time.Sleep处理Ctrl+C中断?
批量删除工具的Ctrl+C中断优化方案
问题描述
我编写了一个批量删除文件的工具,通过inFile指定待删除文件列表,每个文件需手动确认,仅输入空内容时才执行删除操作。目前代码中加入time.Sleep处理Ctrl+C中断:若移除该语句,按下Ctrl+C后stdinScanner.Scan()返回false且无错误,文本为空,导致当前文件被误删;加入sleep可避免此问题,但方案不够优雅。
工具代码如下:
stdinScanner := bufio.NewScanner(os.Stdin) fileScanner := bufio.NewScanner(inFile) for fileScanner.Scan() { target := strings.TrimSpace(fileScanner.Text()) if len(target) > 0 { printUtf16("Delete %s?\n", target) stdinScanner.Scan() if len(stdinScanner.Text()) > 0 { fmt.Println("Non empty return not allowed") os.Exit(1) } else { // TROUBLE: Had to sleep here or interrupt does not work time.Sleep(100 * time.Millisecond) e := os.Remove(target) if e != nil { panic(e) } printUtf16("%s deleted\n", target) } } }
替代方案:捕获SIGINT信号并检查中断状态
核心思路是通过Go的os/signal包捕获Ctrl+C触发的SIGINT信号,设置一个中断标志,在执行删除操作的关键节点检查该标志,一旦检测到中断就退出流程,避免误删。
修改后的代码示例
import ( "bufio" "fmt" "os" "os/signal" "strings" "syscall" ) var isInterrupted bool func init() { // 创建信号通道,监听SIGINT(Ctrl+C) sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT) // 在goroutine中处理信号,避免阻塞主流程 go func() { <-sigChan isInterrupted = true fmt.Println("\n收到中断信号,终止操作") }() } func main() { // 假设inFile已提前打开 stdinScanner := bufio.NewScanner(os.Stdin) fileScanner := bufio.NewScanner(inFile) for fileScanner.Scan() { target := strings.TrimSpace(fileScanner.Text()) if len(target) > 0 { printUtf16("Delete %s?\n", target) stdinScanner.Scan() // 检查是否已收到中断信号 if isInterrupted { os.Exit(0) } input := stdinScanner.Text() if len(input) > 0 { fmt.Println("Non empty return not allowed") os.Exit(1) } else { // 再次检查中断,避免等待输入后到删除前的间隙收到信号 if isInterrupted { os.Exit(0) } e := os.Remove(target) if e != nil { panic(e) } printUtf16("%s deleted\n", target) } } } }
关键逻辑说明
- 信号捕获:在
init函数中启动goroutine监听SIGINT信号,一旦收到就将isInterrupted设为true,并提示用户。 - 中断检查:在两个关键节点检查中断状态:
- 读取用户输入后立即检查,避免用户按下Ctrl+C后直接进入删除流程
- 执行删除操作前再次检查,覆盖输入完成后到删除前的时间间隙
- 无延迟响应:不需要依赖
time.Sleep,中断信号会被实时捕获并处理,逻辑更可靠也更优雅。
内容的提问来源于stack exchange,提问作者user1763590
相关产品推荐
相关产品推荐

