go语言通用的IO模型-4个基本系统调用
2011 年 4 月 14 日
所有执行I/O操作的系统调用,都使用一个非负整数(文件描述符)来描述打开的文件(文件、管道、socket、终端、设备)。
常见的3种文件描述符:
文件描述符 | 用途 | POSIX名称 | stdio流 |
---|---|---|---|
0 | 标准输入 | STDIN_FILENO | stdin |
1 | 标准输出 | STDOUT_FILENO | stdout |
2 | 标准错误 | STDERR_FILENO | stderr |
通用IO模型的4个系统调用
下面的四个系统调用为c语言的形式
- fd = open(pathname, flags, mode):pathname是打开的文件名,flags指定文件的打开方式,mode指定文件的访问权限,返回的fd为上文所说的文件描述符
- num = read(fd, buffer, count):从buffer中读取至多n个字节的数据
- num = write(fd, buffer, count):从buffer中写入至多n个字节的数据,返回num可能小于count(不清楚什么情况)
- status = close(fd)
在golang中,我们也可以通过标准库syscall包使用系统调用
- func Open(path string, mode int, perm uint32) (fd int, err error)
- func Read(fd int, p []byte) (n int, err error)
- func Write(fd int, p []byte) (n int, err error)
- func Close(fd int) (err error)
可见golang的系统调用没有count参数,默认Buffer的大小为count的长度。
下面是一段代码,用来进行文件的复制,没有检查全部的error
func Copy(oldFile, newFile string) { inputFd, err := syscall.Open(oldFile, os.O_RDONLY, 0666) if err != nil { panic(err) } // 此处用到了部分flags指定文件的打开方式,mode指定文件的访问权限下一篇继续 outputFd, err := syscall.Open(newFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0666) if err != nil { panic(err) } defer syscall.Close(inputFd) defer syscall.Close(outputFd) buff := make([]byte, 10) for { size, _ := syscall.Read(inputFd, buff) if size == 0 { break } syscall.Write(outputFd, buff[:size]) } }