golang csv.write 没有写入但没有错误
golang csv.write not writing but no errors
我正在尝试打开现有的 csv 文件并写入;但是,文件 returns 是空的。这是我的代码。
file, err := os.Open("file.csv")
if err != nil {
log.WithError(err)
}
defer file.Close()
w := csv.NewWriter(file)
defer w.Flush()
var headers = []string{"h1", "h2", "h3", "h4"}
writeHeadersErr := w.Write(headers)
if writeHeadersErr != nil {
log.WithError(writeHeadersErr)
file.Close()
}
不确定如何解决这个问题,因为我没有看到任何错误记录。
您需要检查来自 Flush()
的 error
:
w.Flush()
if err := w.Error(); err != nil {
log.Fatal(err) // write file.csv: bad file descriptor
}
这将表明您打开的文件是为了阅读而不是写作。所以要修复:
//file, err := os.Open("file.csv") // read file
file, err := os.Create("file.csv") // create file
if err != nil {
log.Fatal(err)
}
os.Open
opens a file in read-only mode. You should use os.OpenFile
改为:
os.OpenFile("file.csv", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
仅供参考,请注意 os.Create
也有效,但如您所述,如果文件已存在,它会截断该文件。这可能是也可能不是您想要的。
至于为什么你看不到错误,这是因为写入被缓冲并且内容在你调用 w.Flush
之前并没有真正写入。 w.Write
文档中提到了这一点:
Writes are buffered, so Flush must eventually be called to ensure that the record is written to the underlying io.Writer.
虽然 w.Flush
本身在您的代码中被延迟了,并且 return 也不是错误。您可以使用 w.Error()
.
检查错误
如果将这两个调用放在函数的末尾,如下所示,您最终会看到错误:
file, err := os.Open("file.csv")
if err != nil {
log.WithError(err)
}
defer file.Close()
w := csv.NewWriter(file)
// ... write to the file
w.Flush()
err = w.Error() // write file.csv: bad file descriptor
事实上,错误意味着您打开文件时使用了错误的模式标志。更多详情见:
如果您想继续延迟 w.Flush()
,请将其与 w.Error()
一起放在函数文字中,如果与命名的 return 参数结合使用,则可以传播错误,如果有的话。
例如:
func writeToCsv() (err error) {
// ...open file
w := csv.NewWriter(file)
defer func() {
w.Flush()
err = w.Error()
}()
// ...rest of the function
}
我正在尝试打开现有的 csv 文件并写入;但是,文件 returns 是空的。这是我的代码。
file, err := os.Open("file.csv")
if err != nil {
log.WithError(err)
}
defer file.Close()
w := csv.NewWriter(file)
defer w.Flush()
var headers = []string{"h1", "h2", "h3", "h4"}
writeHeadersErr := w.Write(headers)
if writeHeadersErr != nil {
log.WithError(writeHeadersErr)
file.Close()
}
不确定如何解决这个问题,因为我没有看到任何错误记录。
您需要检查来自 Flush()
的 error
:
w.Flush()
if err := w.Error(); err != nil {
log.Fatal(err) // write file.csv: bad file descriptor
}
这将表明您打开的文件是为了阅读而不是写作。所以要修复:
//file, err := os.Open("file.csv") // read file
file, err := os.Create("file.csv") // create file
if err != nil {
log.Fatal(err)
}
os.Open
opens a file in read-only mode. You should use os.OpenFile
改为:
os.OpenFile("file.csv", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
仅供参考,请注意 os.Create
也有效,但如您所述,如果文件已存在,它会截断该文件。这可能是也可能不是您想要的。
至于为什么你看不到错误,这是因为写入被缓冲并且内容在你调用 w.Flush
之前并没有真正写入。 w.Write
文档中提到了这一点:
Writes are buffered, so Flush must eventually be called to ensure that the record is written to the underlying io.Writer.
虽然 w.Flush
本身在您的代码中被延迟了,并且 return 也不是错误。您可以使用 w.Error()
.
如果将这两个调用放在函数的末尾,如下所示,您最终会看到错误:
file, err := os.Open("file.csv")
if err != nil {
log.WithError(err)
}
defer file.Close()
w := csv.NewWriter(file)
// ... write to the file
w.Flush()
err = w.Error() // write file.csv: bad file descriptor
事实上,错误意味着您打开文件时使用了错误的模式标志。更多详情见:
如果您想继续延迟 w.Flush()
,请将其与 w.Error()
一起放在函数文字中,如果与命名的 return 参数结合使用,则可以传播错误,如果有的话。
例如:
func writeToCsv() (err error) {
// ...open file
w := csv.NewWriter(file)
defer func() {
w.Flush()
err = w.Error()
}()
// ...rest of the function
}