当前位置: 首页 > Linux

【golang系统编程】通用IO模型

时间:2023-04-06 01:26:12 Linux

所有进行I/O操作的系统调用都使用一个非负整数(文件描述符)来描述打开的文件(文件、管道、套接字、终端、设备)。三种常见的文件描述符:文件描述符使用POSIX名称stdiostream0标准输入STDIN_FILENOstdin1标准输出STDOUT_FILENOstdout2标准错误STDERR_FILENOstderr通用IO模型的4个系统调用以下四个系统调用的形式为c语言fd=open(pathname,flags,mode):pathname是打开的文件名,flags指定文件的打开方式,mode指定文件的访问权限,返回的fd就是上面提到的文件描述符num=read(fd,buffer,count):Readuptonbytesofdatafromthebuffernum=write(fd,buffer,count):从buffer中写入最多n字节数据,returnnum可能小于count(不清楚是什么情况)status=close(fd)在golang中,我们也可以使用系统调用funcOpen(pathstring,modeint,permuint32)(fdint,errerror)funcRead(fdint,p[]byte)(nint,errerror)funcWrite(fdint,p[]byte)(nint,errerror)funcClose(fdint)(errerror)可以看出golang的系统调用没有count参数,默认的buffersize为计数的长度。下面是一段不检查所有error就复制文件的代码funcCopy(oldFile,newFilestring){inputFd,err:=syscall.Open(oldFile,os.O_RDONLY,0666)iferr!=nil{panic(err)}//这里使用了一些flags来指定文件的打开方式,mode指定了文件的访问权限。下篇继续outputFd,err:=syscall.Open(newFile,os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND,0666)iferr!=nil{panic(err)}defersyscall.Close(inputFd)defersyscall.Close(outputFd)buff:=make([]byte,10)for{size,_:=syscall.Read(inputFd,buff)ifsize==0{break}syscall.Write(outputFd,buff[:size])}}系统调用的详细open()打开函数会返回如下错误:syscall.EACCES:filepermissionItisnotallowedtoopenthefilewithspecifiedflagsparameter.可能的原因是目录权限限制,文件不存在无法创建syacall。EISDIR:调用者尝试打开目录以写入文件系统调用。EMFILE:进程打开的文件描述符数量已达到进程资源限制系统调用的上限。ENFILE:打开文件数已达到系统允许的上限(EMFILE为进程上限)syscall.ENOENT:文件或路径不存在,未指定O_CREAT标志(此错误较多常见)syscall.EROFS:试图打开只读文件syscall.ETXTBSY:指定的文件是可执行文件并且正在运行。系统不允许运行的程序在系统调用中有Create系统调用,但是在golang中,这个funcCreate(pathstring,modeuint32)(fdint,errerror)是使用open()系统调用实现的。read()如果read调用成功,返回实际读取的字节数,如果文件结束(EOF)则返回0。write()num,err:=syscall.Write(fd,buff),num为写入次数,一般等于len(buff),当num