gpt4 book ai didi

io - 在 Go 中使用 ioutil.ReadFile() 读取 1200 多个文件时出错

转载 作者:IT王子 更新时间:2023-10-29 00:48:18 27 4
gpt4 key购买 nike

我正在尝试读取目录中的所有文件 (+10.000),但是当我处理了大约 1400 个文件时,我收到“打开的文件太多”错误。我已经添加了对垃圾收集器的显式调用,但这似乎对我的问题没有多大作用。我检查了 ioutil 包的源代码,ReadFile 在内部使用了 defer file.Close()(正如预期的那样)。那么这里出了什么问题?

    const TEMPLATE = `{ "source_db" : "CDARCHIEF", "doc_type" : "%s", "referentie" : "%s", "bestandsnaam" : "%s", "tekst" : "%s" }`
const MAPPING = `{ ... }`

var DIR, DOCTYPE, URL string

func init() {
flag.StringVar(&DIR, "d", "./", "de directory met de ge-ocrde bestanden")
flag.StringVar(&DOCTYPE, "t", "AG", "document type [ AG, CO, NN ]")
flag.StringVar(&URL, "url", "...", "url voor de juiste index")
}

func main() {
flag.Parse()
fmt.Println("CD Archive Importer")
importDocuments()
}

func importDocuments() {
logfile, _ := os.Create("./importer.log")
defer logfile.Close()

files, _ := ioutil.ReadDir(DIR)
error_counter := 0

for i, file := range files {
if math.Mod(float64(i), 400.0) == 0.0 {
runtime.GC()
fmt.Println("Running garbage collector")
}

fmt.Printf("Importing ( %d / %d ) [ errors: %d ]\r", i+1, len(files), error_counter)

contents, err := ioutil.ReadFile(DIR + "/" + file.Name())
if err != nil {
error_counter = error_counter + 1
logfile.WriteString(fmt.Sprintf("[ERROR/IO] : %s | %s\n", file.Name(), err))
continue
}

contents_string := strings.Replace(string(contents), "\n", " ", -1)
contents_string = strings.Replace(contents_string, "\"", " ", -1)
contents_string = strings.Replace(contents_string, "\\", " ", -1)

referentie := strings.Trim(file.Name(), ".txt")
message := strings.NewReader(fmt.Sprintf(TEMPLATE, DOCTYPE, referentie, file.Name(), contents_string))

resp, error := http.Post(URL, "application/json", message)
if error != nil {
error_counter = error_counter + 1
logfile.WriteString(fmt.Sprintf("[ERROR/NET] : %s | %s | %s\n", file.Name(), resp.Status, error))
continue
}
defer resp.Body.Close()

if resp.StatusCode != 201 {
body, _ := ioutil.ReadAll(resp.Body)
error_counter = error_counter + 1
logfile.WriteString(fmt.Sprintf("[ERROR/ES] : %s | %s | %s\n", file.Name(), resp.Status, string(body)))
}

}

fmt.Println("\nDone!")
}

我知道大约 2 年前有一个有点类似的问题,但对我的问题没有有用的答案。

最佳答案

您可能需要考虑使用 filepath.Walk .我已经成功地在 10k+ 个文件上使用它,没有遇到任何问题。或者,您可以深入研究源代码,看看他们在资源管理方面是否做了任何不同的事情。

此外,for 循环看起来有点古怪,您可以只使用整数和 % 运算符。

for i := 0; i < 1000000; i += 1 {
if i % 5000 == 0 {
fmt.Println(i)
}
}

关于io - 在 Go 中使用 ioutil.ReadFile() 读取 1200 多个文件时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23362632/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com