在使用 range 循环迭代时,遇到将条目写入 CSV 文件的问题

huangapple go评论83阅读模式
英文:

Problem writing entries to CSV file while iterating using range loop

问题

在这段代码中,我试图读取一个目录中的书名,然后将它们写入一个CSV文件,但是它只写入了第一本书的标题到CSV文件中。我不知道如何让它继续工作。

package main

import (
	"encoding/csv"
	"io/ioutil"
	"log"
	"os"
)

func main() {
	files, err := ioutil.ReadDir("/home/bilal/Documents/Books/English")
	if err != nil {
		log.Fatal(err)
	}

	csvFile, err := os.Create("English.csv")
	if err != nil {
		log.Fatal(err)
	}

	for _, file := range files {
		// fmt.Println(file.Name())
		fileData := []string{
			file.Name(),
		}
		csvWriter := csv.NewWriter(csvFile)

		csvWriter.Write(fileData)

		csvWriter.Flush()
		csvFile.Close()
	}
}
英文:

In this code, I am trying to read the book titles in a directory and then write them in a CSV file but it is writing only the first book title in a CSV file. I don't know how to make it work further.

package main

import (
	"encoding/csv"
	"io/ioutil"
	"log"
	"os"
)

func main() {
	files, err := ioutil.ReadDir("/home/bilal/Documents/Books/English")
	if err != nil {
		log.Fatal(err)
	}

	csvFile, err := os.Create("English.csv")
	if err != nil {
		log.Fatal(err)
	}

	for _, file := range files {
		// fmt.Println(file.Name())
		fileData := []string{
			file.Name(),
		}
		csvWriter := csv.NewWriter(csvFile)

		csvWriter.Write(fileData)

		csvWriter.Flush()
		csvFile.Close()
	}
}

答案1

得分: 4

问题在于你在循环内部关闭了文件,所以在第一次迭代之后它就已经关闭了。此外,没有必要在循环内部创建csvWriter,你可以在循环结束后创建一个并在循环之后刷新它。注意,你可以使用延迟语句来设置文件句柄和写入器的清理代码(这样,你就不必担心在函数的任何可能返回的地方显式包含清理代码)。在离开函数之前,延迟语句将按照相反的顺序执行,所以在下面的示例中,csvWriter.Flush()将在csvFile.Close()之前执行,如预期所示:

// ...
csvFile, err := os.Create("English.csv")
if err != nil {
    log.Fatal(err)
}
defer csvFile.Close()

csvWriter := csv.NewWriter(csvFile)
defer csvWriter.Flush()

for _, file := range files {
    fileData := []string{ file.Name() }
    csvWriter.Write(fileData)
}
// ...
英文:

The problem is that you are closing the file inside the loop, so after the first iteration it's already closed. Also, there's no need to create csvWriter inside a loop, you can create one and flush it after the loop. Note that you can use defer statements to set the cleanup code for both the file handle and the writer right after creating them (in this way, you don't have to worry about including cleanup code explicitly everywhere the control flow may return from the function). Before leaving the function, defer statements will be executed in the reverse order, so in the example below csvWriter.Flush() will be executed before csvFile.Close(), as expected:

// ...
csvFile, err := os.Create("English.csv")
if err != nil {
    log.Fatal(err)
}
defer csvFile.Close()

csvWriter := csv.NewWriter(csvFile)
defer csvWriter.Flush()

for _, file := range files {
    fileData := []string{ file.Name() }
    csvWriter.Write(fileData)
}
// ...

huangapple
  • 本文由 发表于 2022年6月15日 01:44:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/72621328.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定