liunx下的文件IO与标准IO

一、系统调用

1、系统提供的用于用户空间访问内核空间数据的一组函数。(例如我们写一个程序想读取或修改一个文件的内容,而文件在计算机是存储在磁盘的,即需要访问硬件。在计算机中,用户和硬件之间隔了一个操作系统,想要操作硬件必须得到操作系统的许可,这个需要的权限是很高的。因此,为了方便使用,产生了系统调用的概念。系统提供一系列函数接口,我们可以调用这些函数,访问指定的文件,系统帮我们完成相应的操作,此时并不需要很高的权限。)

简而言之,无系统调用前,想要访问文件,需要得到操作系统很高的权限,此时你可以访问任何文件。有系统掉调用后,通过函数接口,无需权限,但只能访问指定的文件,由系统完成操作。既方便又保护了计算机

二、库函数

1、标准c库函数,即用标准c实现的一组函数。(库函数也能实现访问文件,相当于在系统调用函数再进行了一次封装,主要目的是减少系统调用的次数,节省时间)

三、流和文件描述符

1、标准IO通过FILE *(流)操作文件,文件IO通过文件描述符操作文件。(FILE *是c语言定义的关于文件专用的结构体指针,这个结构体的成员保存着文件的属性)(文件描述符是非零的整数,在liunx中0,1,2已经分给了,三个文件标准输入(stdin),标准输出(stdout),标准错误(stderr),这三个文件是我们打开终端默认打开的,分别是我们在终端的输入,终端的输出,出错时终端的输出)(文件描述符是有限的,文件描述符满了则无法通过文件IO访问文件,属于一种资源,使用后要及时释放)

2、文件IO无缓冲区,标准IO有缓冲区。(文件IO的操作函数有open(打开文件)/read(读文件)/write(写文件)/close(关闭文件))(标准IO的操作函数有fopen()打开文件/fclose()关闭文件/fread()块读/fwrite()块写/fgets()行读/fputs()行写/fgetc()字符读/fputc()字符写)(标准IO有缓存区是库函数减少系统调用次数的体现。缓冲区可以理解成一个数组,标准IO读文件的时候,会直接向内核(操作系统的核心包括文件管理的部分)直接读取一大段文件,然后用户再在这个缓冲区里面读文件,读一些,缓冲区的内容就少一些,当缓冲区的内容空的时候,再向内核读取一大段的文件。写操作类似,用户的要写的内容先放到缓冲区,等到缓冲区满的时候,再将缓冲区的内容写到文件。主要目的就是减伤系统调用的次数,节省时间,提高效率)

3、标准IO分为全缓存、行缓存、不缓存。(全缓存和上述一样,列如fopen打开文件为全缓存,大小为4096个字节。行缓存是当缓冲区遇到换行符就实施相应的文件操作,如stdin、stdout,大小为1024个字节。无缓存就是无缓冲区,如stderr)(可以使用fflush()函数强制刷新缓冲区,头文件为#include <stdio.h> ,形参只有一个流,返回值为int型,成功返回0,失败返回EOF(-1),并设置错误号)

4、所有的IO操作仅是简单的从程序移进或者移除,这种字节流,就称为流。(分为文本流和二进制流,文本流中,数据都是以字符出现。二进制流中数据是二进制序列。不同的操作系统对文本流和二进制流的定义不一样。liunx中不区分文本流和二进制流,都是二进制流)

四、标准IO(标准输入输出函数)

1、标准c库提供的一组用于输入输出的函数 (头文件都为#include <stdio.h>)

2、

        fopen()(打开文件)

        函数原型:FILE * fopen(const char *pathname, const * mode)(第一个形参表示要打开文件的路径,第二个形参表示打开文件的方式)(const限定了传过来的地址取*不能被改变)

        mode:打开文件方式的指针(“r”:是只读方式打开存在的文件,“r+”:是读写方式打开存在的文件,“w”:只写方式打开文件,文件不存在则创建,存在则清空,“w+”:读写方式打开文件,文件不存在则创建,存在则清空,“a”:只写方式追加(不清空),其他与“w”一样,“a+”:读写方式追加),其他与“w+”一样。

        返回值 成功为 FILE * 失败为:NULL,并且设置errno的值,可以使用perror打印错误(perror头文件也为#include <stdio.h>)

        fgetc()/fputc()(单个字符读取和写入)

        函数原型: int fgetc(FILE * stream)

        返回值 成功返回读取到的字符 失败返回EOF (此时的字符用的int表示)

        fgets()/fputs(一行字符读取和写入)

        函数原型: char * fgets(char *s,int size,FILE *stream)(s保存缓冲区的地址,size指定读取的大小,stream表示流)

         返回值 成功返回缓冲区的首地址 失败返回NULL

        fread()/fwrite (一块字符的读取和写入)

        函数原型:size_t fread(void *ptr,size_t size,size_t nmemb ,FILE *stream)(ptr :缓冲区首地址,size:每个对象的大小,nmemb:对象数,stream:流)

        返回值: 成功返回对象数 nmemb 失败返回 0

        fclose()(关闭文件)

        函数原型:int fclose(FILE *stream)

        返回值 成功返回0 失败返回EOF 并设置错误号

        fseek()(改变文件指针位置)

        函数原型:int fseek(FILE * stream,long offset,int whence)(stream:流,offset:文件指针偏移量,whence:文件指针位置)

        whence:SEEK_SET(文件指针在开头位置),SEEK_CUR(文件指针在当前位置),SEEK_END(文件指针在结尾位置)

        返回值: 成功返回0 失败返回-1

        void rewind(FILE * stream)(将文件指针重置为开头位置)

        long ftell(FILE * stream)(查看文件指针位置,返回值为偏移量)

五、文件IO

1、文件描述符fd:在程序中标识操作文件的一个非负整数

2、文件IO接口函数

        close()(关闭文件描述符)

        头文件:#include <unistd.h>

        函数原型:int close(int fd)

        返回值:成功 返回0 失败:返回-1,并设置错误码

        open ()(打开文件)

        头文件:#include <sys/types.h>  #include <sys/stat.h>  #include <fcntl.h>

        函数原型:int open(const char*pathname,int flags) int open(const char *pathname,int flags,mode_t mode)(当第二形参或上O_CREAT参数时,会有第三个形参)

        参数说明:pathname:文件的打开路径

                          flags:文件的打开方式(O_RDONLY(只读),O_WRONLY(只写),O_RDWR()可读可写,这三个参数必须选择一个)(其他参数:O_CREAT(文件不存在则创建,文件权限由第三个参数决定),O_APPEND(追加的形式进行写入文件),O_EXCL(需要和O_CREAT一起使用,创建文件时,文件已存在则报错),O_TRUNC:截断打开文件,文件内容将被清空)(注意:第二个形参参数之间用'|'连接,不要'||')

                          mode:指定文件创建时的用户的操作权限(如0777,最后会与上文件掩码,才是最终的权限)

        返回值:成功:返回文件描述符 失败:返回-1,并设置错误号

        read() (读文件)

        头文件:#include <unistd.h>

        函数原型:ssize_t read(int fd,void *buf,size_t count) (ssize_t 是c语言库定义的一种int 类型的别名)

        参数说明:fd:想要读取的文件描述符

                          buf:缓冲区地址

                          count:想要读取的数据大小

        返回值:成功:返回读取的字节数 失败返回-1,并设置错误号

        write()(写文件)

        头文件:#include <unistd.h>

        函数原型:ssize_t write(int fd,void *buf,size_t count) (ssize_t 是c语言库定义的一种int 类型的别名)

        参数说明:fd:想要读取的文件描述符

                          buf:缓冲区地址

                          count:想要读取的数据大小

        返回值:成功:返回写入的字节数 失败返回-1,并设置错误号

        lseek()(改变文件指针)

        头文件:#include  <sys/types.h> #include <unistd.h>

        函数原型:off_t lseek(int fd,off_t offset,int whence)

        参数说明:fd:文件描述符

                        offset:偏移量

                        whence:文件指针开始位置(SEEK_SET:文件开头,SEEK_CUR:文件当前位置,SEEK_END:文件结尾)

       返回值:成功返回偏移量 失败返回-1,并设置错误号

六、文件目录操作相关函数接口

1、stat()/fstat()/lstat() (获取文件的详细信息)(lstat可以得到链接文件的信息)

        头文件:#include <sys/types.h>

                      #incdude <sys/stat.h>

                      #include <unistd.h>

        函数原型:int stat(const char *pathname,struct stat *statbuf)

                          int fstat (int fd,struct stat*statbuf)

                          int lstat (const char *pathname,struct stat* stat)

        函数的参数说明:pathname:文件路径

                                     fd:文件描述符

                                     statbuf:存储文件信息的结构体指针

        返回值: 成功返回0,失败返回-1并设置错误号     

(这个函数的用法,我们先定义一个struct stat 类型的结构体变量,第二个形参就传结构体变量的地址,内核会将文件信息复制到我们定义的结构体变量的成员中,我们就可以访问结构体变量成员得到文件信息)

        struct stat

        {

                st_size;文件大小

                st_mode:文件属性

                st_nlink:文件的链接数

                st_uid:文件所属用户id

                st_gid:文件所属组id

                st_ino:文件inode号

                st_ctime:文件最后被修改的时间

        };

        st_mode参数说明:( man 7 inode 可查询详细参数说明)

        检测文件类型的宏函数:S_ISREG(m) (文件是不是普通文件)(形参为结构体成员st_mode)

                                                S_ISDIR(m) (文件是不是目录文件)

                                                S_ISCHR(m)(文件是不是字符设备文件)

                                                S_ISBLK(m)(文件是不是块文件)

                                                S_ISFIFO(m)(文件是不是管道文件)

                                                S_ISLNK(m)(文件是不是链接文件)

                                                S_ISSOCK(m)(文件是不是套接字文件)

        检测文件类型的一些宏:S_IRWXU(用户有读写可执行权限)(用法与st_mode相与看结果是否为1)

                                                S_IRUSR(用户有读权限)

                                                S_IWUSR(用户有写权限)

                                                S_IXUSR(用户有可执行权限)

                                                S_IRWXG(组用户有读写可执行权限)

                                                S_IRGRP(组用户有读权限)

                                                S_IWGRP(组用户有写权限)

                                                S_IXGRP(组用户有可执行权限)

                                                S_IRWXO(其他用户有读写可执行权限)

                                                S_IROTH(其他用户有读权限)

                                                S_IWOTH(其他用户有写权限)

                                                S_IXOTH(其他用户有可执行权限)

2、getpwuid()(获取用户名的函数)

头文件:#include <sys/types.h>

              #include  <pwd.h>

函数原型:struct passwd *getpwuid(uid_t uid)(用法和stat类似,我们先创建一个与返回值类似的结构体指针来接收返回值,然后用这个访问结构体成员即用户名,形参为用户的uid号,可以用st_uid)

返回值是一个结构体指针,我们可以通过这个结构体指针访问它的成员,其中就包括用户名

 

getgrgid()(获取组名的函数)

头文件:#include <sys/types.h>

              #include <grp.h>

函数原型:struc group *getgrgid(gid_t gid)(用法同上)

返回值是个结构体指针。

 localtime()(将以秒的总时间转化为年月日时间)

头文件:#include <time.h>

函数原型:struct tm* localtime(const  time_t *timep)(用法和上面函数类似,都需要先创建与返回值类似的结构体指针,然后通过结构体指针访问成员,形参为秒数的地址,记得要写取地址符,在stat函数中有st_ctime可以实现,要注意这是因为重定义过了)

 

返回值是个结构体指针struct tm*

注意: 访问年时,要加上1900,访问月要加上1

3.、opendir()(打开目录文件)

头文件:#include <sys/types.h>

              #include <dirent.h>

函数原型:DIR *opendir(const char *name)

参数说明:name:目录的路径

返回值: 成功返回目录流指针 失败返回NULL,设置错误码

readdir()(读取目录文件信息)                

头文件:#include <dirent.h>

函数原型:struct dirent *readdir(DIR *dirp)

参数说明:dirp:就是上个函数的返回值目录流指针

返回值和stat函数一样式结构体指针,我们还是先创建与返回值类似的结构体指针,用结构体指针访问成员,即文件内容

 

注意:srat()、getpwuid()、getgrgid()、localtime()、opendir()、readdir()这些函数搭配可以写一个简单的ls -l指令

        

        

                                                  

        

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丿浩子不是耗子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值