【问题标题】:How do I solve Golang filepath.walkfunc problem?如何解决 Golang filepath.walkfunc 问题?
【发布时间】:2023-01-27 08:15:53
【问题描述】:

我正在尝试解决一项任务,我必须在具有相似名称和相同大小的其他文件中找到一个包含 CSV 格式数据的文件,并在第 5 行第 3 列(索引 4 和 2)上打印一个数字 所以我写了这段代码

package main

import (
    "encoding/csv"
    "fmt"
    "os"
    "path/filepath"
)

var s [][]string

func walkfunc(path string, info os.FileInfo, err error) error {
    if err != nil {
        return err
    }

    buf, err1 := os.Open(path)
    if err1 == nil {
        var err2 error
        r := csv.NewReader(buf)
        s, err2 = r.ReadAll()
        if err2 == nil {
            fmt.Printf("found: %v", s[4][2])
        }
    }
    defer buf.Close()
    return nil
}
func main() {
    const root = "./task/"
    if err := filepath.Walk(root, walkfunc); err != nil {
        fmt.Printf("error: %v", err)
    }
}

我在输出中得到了这个

GOROOT=/usr/local/go #gosetup
GOPATH=/usr/local/go/bin #gosetup
/usr/local/go/bin/go build -o /private/var/folders/j2/ybr0drz13yq31dc67zmvkb1w0000gn/T/GoLand/___go_build_qwasd3_go /Users/user/Downloads/zadacha/qwasd3.go #gosetup
/private/var/folders/j2/ybr0drz13yq31dc67zmvkb1w0000gn/T/GoLand/___go_build_qwasd3_go
panic: runtime error: index out of range [4] with length 3

goroutine 1 [running]:
main.walkfunc({0x14000018120?, 0x0?}, {0x14000098d88?, 0x10247fe40?}, {0x0?, 0x0?})
        /Users/user/Downloads/zadacha/qwasd3.go:23 +0x28c
path/filepath.walk({0x14000018120, 0xe}, {0x1024c9cf8, 0x140000685b0}, 0x1024c9338)
        /usr/local/go/src/path/filepath/path.go:433 +0xd0
path/filepath.walk({0x10248d4a8, 0x7}, {0x1024c9cf8, 0x140000684e0}, 0x1024c9338)
        /usr/local/go/src/path/filepath/path.go:457 +0x1fc
path/filepath.Walk({0x10248d4a8, 0x7}, 0x1024c9338)
        /usr/local/go/src/path/filepath/path.go:520 +0x6c
main.main()
        /Users/user/Downloads/zadacha/qwasd3.go:37 +0x30

Process finished with the exit code 2

我究竟做错了什么?

我试图在 MacBook 上运行这段代码。 所需文件包含带数字的表格,我需要在第 5 行和第 3 列打印一个数字。

【问题讨论】:

  • 处理文件没有预期行数和列数的情况:if len(s) < 5 || len(s[4]) < 3 { do something }
  • 我确定我需要的文件具有所需的行数和列数。所有其他文件都有非 CSV 数据,因此它们根本没有行或列。
  • 在出现恐慌的行之前添加:if len(s) < 5 || len(s[4]) < 3 { fmt.Println(path) }。确认打印的文件名是您所期望的,并且该文件包含预期的行数和列数。

标签: go


【解决方案1】:

我没有看到的一件事是在打开文件并尝试将其作为 CSV 读取之前检查文件是否实际上是 CSV。

CSV 阅读器可能能够将普通的 txt 文件解释为 CSV,例如:

buf := strings.NewReader(`A regular text file with 3 lines.
Line2
Line3
`)

r := csv.NewReader(buf)
records, _ := r.ReadAll()

fmt.Println(records)

印刷:

[[A regular text file with 3 lines.] [Line2] [Line3]]

假设它是一个具有正确行数和列数的 CSV,就像我看到的那样:

fmt.Println(records[4][2])

给出您分享的恐慌信息:

panic: runtime error: index out of range [4] with length 3

因此,您至少需要检查 records 是否有 5 行,如果有,则在尝试读取之前检查第 5 行是否有 3 列场地:

if len(records) < 5 {
    fmt.Println(path, "does not have 5 rows")
    continue
}

if len(records[4]) < 3 {
    fmt.Println(path, "5th row does not have 3 columns")
    continue
}

fmt.Println(path, records[4][2])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-07
    • 2016-11-15
    • 2011-01-04
    • 2012-03-22
    • 2021-12-22
    • 2017-10-04
    • 2020-08-05
    • 1970-01-01
    相关资源
    最近更新 更多