5

golang 可能出现文件打开但是报错的情况吗

 1 year ago
source link: https://www.v2ex.com/t/947492
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

V2EX  ›  Go 编程语言

golang 可能出现文件打开但是报错的情况吗

  Assassinrx · 20 小时 23 分钟前 · 802 次点击
正常打开文件的模式代码就是这样,我想问下各位大佬可能出现 err 不为空但是文件被打开的情况吗

file, err := os.Open("filename.txt")
if err != nil {
// 处理错误
}
defer file.Close()

因为我想的是可能这么写更好些?

file, err := os.Open("filename.txt")
defer file.Close() // defer 写在 err 前面
if err != nil {
// 处理错误
}
24 条回复    2023-06-11 02:22:15 +08:00
seers

seers      20 小时 4 分钟前

defer 是在 return 前才调用
Assassinrx

Assassinrx      19 小时 57 分钟前

@seers 但是一般 error 里面就返回了
R0n1n

R0n1n      19 小时 57 分钟前

出错了也就不用再去关闭句柄了,所以一般是先判断 err 吧
zhs227

zhs227      19 小时 52 分钟前

第一个 os.Open 如果返回了 err ,那么 file 必定是 nil ,这种情况下不需要 Close 。只有 err == nil 的情况下,才需要在最结尾 close 。
当然如果按你下面的写法也没错,实际上 file.Close 当 file==nil 的时候,会返回一个 ErrInvalid ,这个你看一下 go 的源码就清楚了。
twistedmeadows

twistedmeadows      19 小时 51 分钟前 via iPhone

gpt 答案:
在 Go 语言中,如果在尝试打开文件时返回的 err 不为 nil ,那么这意味着在打开文件的过程中出现了一些错误。在这种情况下,file 变量通常会是 nil ,所以你无法或者不需要调用 file.Close()。

全文:
https://chat.openai.com/share/bb186187-feb5-4970-b36f-6c0914f6e668
lasuar

lasuar      19 小时 51 分钟前

看下源码 不就知道了,正常的接口设计不会出现你说的情况
Assassinrx

Assassinrx      19 小时 49 分钟前

@R0n1n 所以我多想了一下,是 golang 都有这个标准,出现 err 就不需要管别的返回了,还是说 err 存在但是 file 也打开了的情况
Assassinrx

Assassinrx      19 小时 47 分钟前

@zhs227 源码是写的 nil ,但是可不可能在系统层面还是打开的,也就是文件里面的引用指针还是+1 了的情况,这块研究不深,所以想问问大佬们
Assassinrx

Assassinrx      19 小时 45 分钟前

@lasuar 我能理解,毕竟这个底层也是 golang 官方库,只是好奇的想确认下文件这块的操作流程是不是符合预期
zhs227

zhs227      19 小时 43 分钟前

Close 的代码你看一下就懂了,返回为 nil 的时候根本就没涉及到资源处理。
func (f *File) Close() error {
if f == nil {
return ErrInvalid
}
return f.file.close()
}


Open 的代码:
func OpenFile(name string, flag int, perm FileMode) (*File, error) {
testlog.Open(name)
f, err := openFileNolog(name, flag, perm)
if err != nil {
return nil, err
}
f.appendMode = flag&O_APPEND != 0

return f, nil
}

要么 f 有值,err==nil ,要么 f==nil ,err 有值。只有这两种可能。而 err 有值的情况下,f==nil 也是不用 close 的。
aeof

aeof      19 小时 42 分钟前 via Android

不可能出现
Assassinrx

Assassinrx      19 小时 35 分钟前

@zhs227 好像懂了。也就是 golang 这块 我只要做到正常的处理就行了,底层它内部调用的文件系统是否关闭了文件,我这边也处理不到了。原本是想了解下这个底层是否关闭了,影不影响上层处理。,从写 golang 逻辑下,正常写法就已经是完美了。
Assassinrx

Assassinrx      19 小时 34 分钟前

@aeof 行!
harrozze

harrozze      19 小时 11 分钟前

@Assassinrx #8 既然用 go 的库,那么“如果 Open 返回的 err 不为 nil ,而实际系统层面文件是打开的”这件事情应该是 go 需要考虑的,甚至(如果真是这样的话)算是一个 bug 。

先别想这些细节上的优化,先把代码跑起来,遇到了再说。
Assassinrx

Assassinrx      17 小时 44 分钟前

@harrozze 确实是这样。至少代码层面开发者能做的都做到了。
admpubcom

admpubcom      17 小时 27 分钟前 via iPhone

代码就在面前,为什么不点进去看一下呢
Jirajine

Jirajine      15 小时 40 分钟前

你只要记住 golang 的 convention 是,调用一个会返回错误的函数时,只在检查完错误之后才能使用其他返回值。没有检查错误或错误不为 nil 时其他返回值都可以认为是无效的,使用此值可以看作 undefined behavior 。
这主要是因为 go 欠缺 union type 。
Assassinrx

Assassinrx      13 小时 46 分钟前

@admpubcom 我可能想的太多了,纯粹好奇问一下
Assassinrx

Assassinrx      13 小时 44 分钟前

@Jirajine 这个是的,确实能理解了
flyqie

flyqie      7 小时 8 分钟前 via Android

@Jirajine #16

没记错的话,io.EOF 是个例外。。

不过它不在 Open 而在 Read 用。
Jirajine

Jirajine      6 小时 21 分钟前

@flyqie 这个我当然知道,所以说这是 convention ,convention 有例外是很正常的。
像这种情况在其他类型严格且表达能力足够的语言中,接口可以返回一个专门的 IOResult ,与普通的 Result 区分。
timpaik

timpaik      5 小时 56 分钟前

约定俗成,标准库里直接可以认为这俩互斥,但没有类型系统保证,第三方库保险起见看看实现就好了
realpg

realpg      4 小时 46 分钟前

golang 提供的官方标准库里,出现了你设想的那种场景,那就是 bug ,golang 官方负责解决,你下层不用想能解决上层的问题。

你引用了的别人的三方库里出现这种问题,那是哪个库作者的 bug ,库作者负责解决这种问题,你下层不用想能解决上层的问题。

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK