文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
底层的原理
Go 的标准库 os
提供了极其方便的封装,深入最原始的本质可以发现最核心的东西: 系统调用 。
Go 标准库的文件存储 IO 就是基于系统调用之上的。可以稍微跟一下 os.OpenFile
的调用:
os 库的 OpenFile
函数:
func OpenFile(name string, flag int, perm FileMode) (*File, error) {
f, err := openFileNolog(name, flag, perm)
if err != nil {
return nil, err
}
f.appendMode = flag&O_APPEND != 0
return f, nil
}
稍微看下 openFileNolog
函数:
func openFileNolog(name string, flag int, perm FileMode) (*File, error) {
var r int
for {
var e error
r, e = syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
if e == nil {
break
}
if runtime.GOOS == "darwin" && e == syscall.EINTR {
continue
}
return nil, &PathError{"open", name, e}
}
return newFile(uintptr(r), name, kindOpenFile), nil
}
可以看到 syscall.Open
,这个函数获取到一个整数,也就是在 c 语言里最常见的 fd 句柄,而 File
结构体则仅仅是基于这个的一层封装而已。
思考下,为什么会有标准库封装这一层存在?
划重点:为了屏蔽操作系统的区别 ,使用这个标准库的所有操作都是跨平台的。换句话说,如果是特殊操作系统才有的特性,那么在 os 库里就找不到对应封装的 IO 操作。
那么怎么使用系统调用?
直接使用 syscall 库,也就是系统调用。从名字也能看出来,系统调用是和操作系统强相关的,因为是操作系统提供的调用接口,所以系统调用会因为操作系统不同而导致不同的特性,不同的接口。
所以,如果直接使用 syscall 库来使用系统调用,那么需要自己来承受系统带来的兼容性问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论