英文:
Close the file before rename it in golang
问题
当我使用golang进行文件操作时,我首先打开一个文件并将close()函数添加到defer列表中,然后尝试重命名该文件。如果我手动关闭文件,defer将再次关闭它。如果我等待defer关闭它,重命名将导致错误,因为它尚未关闭。代码如下所示:
func main() {
pfile1, _ := os.Open("myfile.log")
defer pfile1.Close() //它将再次关闭。
//...
//...
pfile1.Close() //在重命名之前必须关闭它。
os.Rename("myfile.log", "myfile1.log")
}
我发现了一些不太好的解决方案,比如创建另一个函数来分离打开文件的操作,是否有更好的解决方案呢?代码如下所示:
func main() {
var pfile1 *os.File
ugly_solution(pfile1)
os.Rename("myfile.log", "myfile1.log")
}
func ugly_solution(file *os.File) {
file, _ = os.Open("myfile.log")
defer file.Close()
}
英文:
When I do some file operations with golang, I firstly open a file and add the close() into defer list, then I try to rename that file. If I close the file manually, the defer will close it again. If I wait for the defer to close it, the rename will cause error because it is not closed yey. Code as below
func main() {
pfile1, _ := os.Open("myfile.log")
defer pfile1.Close() //It will be closed again.
...
...
pfile1.Close() //I have to close it before rename it.
os.Rename("myfile.log", "myfile1.log")
}
I found some ugly solution, such as create another function to separate the open file, does any better solution that below?
func main() {
var pfile1 *os.File
ugly_solution(pfile1)
os.Rename("myfile.log", "myfile1.log")
}
func ugly_solution(file *os.File) {
file, _ = os.Open("myfile.log")
defer file.Close()
}
答案1
得分: 2
有几个关于你的代码不清楚的地方。
首先,为什么在重命名文件之前要打开文件?这不是os.Rename
函数所要求的。该函数接受两个表示旧文件名和新文件名的字符串,不需要传递文件指针。
func main() {
...
...
os.Rename("myfile.log", "myfile1.log")
}
假设你需要对文件内容进行更改(根据ugly_solution
方法似乎不是这种情况),并且你必须打开文件,那么为什么要延迟file.Close()
?如果你需要在同一个方法中显式调用它,那么就不需要延迟该方法。直接调用即可。
func main() {
pfile1, _ := os.Open("myfile.log")
...
...
pfile1.Close()
os.Rename("myfile.log", "myfile1.log")
}
英文:
There are a few things that are not clear to me about your code.
First of all, why do you open the file before renaming it? This is not required by the os.Rename
function. The function takes two strings representing the old and new file name, there is no need to pass a file pointer.
func main() {
...
...
os.Rename("myfile.log", "myfile1.log")
}
Assuming you need to make changes to the file content (which doesn't seem to be the case given the ugly_solution
method) and you have to open the file, then why deferring file.Close()
? You don't have to defer the method if you need it to be called explicitly somewhere in the same method. Simply call it.
func main() {
pfile1, _ := os.Open("myfile.log")
...
...
pfile1.Close()
os.Rename("myfile.log", "myfile1.log")
}
答案2
得分: 2
你可以在defer语句中同时关闭和重命名文件:
func main() {
pfile1, _ := os.Open("myfile.log")
defer func() {
pfile1.Close()
os.Rename("myfile.log", "myfile1.log")
}()
// ...
// ...
}
英文:
You can put both closing and renaming the file in the defer:
func main() {
pfile1, _ := os.Open("myfile.log")
defer func(){
pfile1.Close()
os.Rename("myfile.log", "myfile1.log")
}()
...
...
}
答案3
得分: 0
在像你的示例中的情况下,也许你想按照以下步骤进行操作:
- 创建一个易于识别的临时文件。
- 写入数据。
- 关闭文件。
- 如果成功,将文件重命名。
在这种情况下,如果你想遵循底层文件的操作,也许你不想延迟对IO.file的关闭,因为你想获取关闭函数本身返回的错误。
此外,在这种情况下,你也许还想执行file.sync()操作。
参考链接:https://www.joeshaw.org/dont-defer-close-on-writable-files/
英文:
In situation like in your sample
Maybe you want to follow this scenario:
- Create easily an identifiable temporary file.
- Write the data.
- Close the file.
- If successful rename the file.
In that case where you want to follow OS system action of underlying files maybe you want to simply not deferring the close on IO.file since you want to get the Error returned by the close function itself.
Also, in that case you maybe want to operate a file.sync() too.
See https://www.joeshaw.org/dont-defer-close-on-writable-files/
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论