Go脚本未进入for循环:逐行处理TSV文件异常求助
问题描述
执行一段逐行读取TSV文件并提取内容写入新文件的Go脚本时,发现跳过表头后脚本直接退出,完全没进入循环执行逻辑。脚本代码如下:
func main() { inFile := "file.tsv" reader, err := os.Open(inFile) if err != nil { log.Println(err) } defer reader.Close() scanner := bufio.NewScanner(reader) scanner.Scan() // skip header for scanner.Scan() { row := strings.Split(scanner.Text(), "\t") outFileName := fmt.Sprintf("./out_name__%s", row[1]) writer, err := os.Create(outFileName) if err != nil { log.Println(err) writer.Close() } writer.Write([]byte(row[2])) writer.Close() } }
问题原因
- 未检查跳过表头的
scanner.Scan()返回值:如果目标文件只有表头行,或者第一次scanner.Scan()因读取错误、文件为空等原因返回false,后续循环的scanner.Scan()条件自然不会触发。 - 未捕获扫描过程中的错误:整个扫描流程没有调用
scanner.Err(),如果文件读取时发生IO错误,会导致扫描提前终止,且无法得知具体错误原因。 - 错误处理逻辑有隐患:创建文件失败时,
writer可能为nil,此时调用writer.Close()会直接触发panic,但你的场景中脚本直接退出,核心原因还是扫描环节的问题。
修复方案
- 检查跳过表头的扫描结果,避免空文件或表头读取失败直接进入循环
- 循环结束后调用
scanner.Err()排查潜在IO错误 - 修正文件写入的错误处理逻辑,避免对
nil的writer执行操作 - 增加行格式校验,避免索引越界panic
修改后的代码示例:
func main() { inFile := "file.tsv" reader, err := os.Open(inFile) if err != nil { log.Fatal(err) // 文件打开失败直接终止流程 } defer reader.Close() scanner := bufio.NewScanner(reader) // 跳过表头,先检查扫描是否成功 if !scanner.Scan() { if err := scanner.Err(); err != nil { log.Fatalf("读取表头失败: %v", err) } log.Println("文件为空或仅包含表头行") return } for scanner.Scan() { row := strings.Split(scanner.Text(), "\t") // 校验行格式,避免索引越界 if len(row) < 3 { log.Println("行格式错误,字段数量不足") continue } outFileName := fmt.Sprintf("./out_name__%s", row[1]) writer, err := os.Create(outFileName) if err != nil { log.Printf("创建文件%s失败: %v", outFileName, err) continue // 跳过当前行,不执行后续写入操作 } _, err = writer.Write([]byte(row[2])) if err != nil { log.Printf("写入文件%s失败: %v", outFileName, err) } writer.Close() } // 检查扫描全程是否有IO错误 if err := scanner.Err(); err != nil { log.Fatalf("文件扫描失败: %v", err) } }
内容的提问来源于stack exchange,提问作者t.ry
相关产品推荐
相关产品推荐

