文件IO与标准IO

一、先来了解下什么是文件I/O和标准I/O:

文件I/O:文件I/O称之为不带缓存的IO(unbuffered I/O)。不带缓存指的是每个read,write都调用内核中的一个系统调用。也就是一般所说的低级I/O——操作系统提供的基本IO服务,与os绑定,特定于linix或unix平台。

标准I/O:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准I/O库处理很多细节。例如缓存分配,以优化长度执行I/O等。标准的I/O提供了三种类型的缓存。

(1)全缓存:当填满标准I/O缓存后才进行实际的I/O操作。 
(2)行缓存:当输入或输出中遇到新行符时,标准I/O库执行I/O操作。 
(3)不带缓存:stderr就是了。

二、二者的区别

      文件I/O 又称为低级磁盘I/O,遵循POSIX相关标准。任何兼容POSIX标准的操作系统上都支持文件I/O。标准I/O被称为高级磁盘I/O,遵循ANSI C相关标准。只要开发环境中有标准I/O库,标准I/O就可以使用。(Linux 中使用的是GLIBC,它是标准C库的超集。不仅包含ANSI C中定义的函数,还包括POSIX标准中定义的函数。因此,Linux 下既可以使用标准I/O,也可以使用文件I/O)。

      通过文件I/O读写文件时,每次操作都会执行相关系统调用。这样处理的好处是直接读写实际文件,坏处是频繁的系统调用会增加系统开销,标准I/O可以看成是在文件I/O的基础上封装了缓冲机制。先读写缓冲区,必要时再访问实际文件,从而减少了系统调用的次数。

      文件I/O中用文件描述符表现一个打开的文件,可以访问不同类型的文件如普通文件、设备文件和管道文件等。而标准I/O中用FILE(流)表示一个打开的文件,通常只用来访问普通文件。

三、相关API

系统IO
          
 1、open()
                #include <sys/stat.h>
                #include <fcntl.h>
                int open(const char *pathname, int flags);
                int open(const char *pathname, int flags, mode_t mode);
                    功能:打开或新建一个文件,并指定打开的方式或新建文件的权限
                    参数:
                        pathname------包含路径的文件名,例如“./a.txt”
                        flags---------文件标志
                            O_RDONLY----只读
                            O_WRONLY----只写
                            O_RDWR------可读可写
                            O_CREAT-----如果文件不存在,新建文件,此时mode才有用
                            O_EXCL------与O_CREAT配合使用,可以用来通过返回值判断文件是否新建成功
                            O_TRUNC-----在文件存在&&是普通文件&&能写入的情况下,文件内容清空
                            O_APPEND----打开文件时,把文件读写指针定位在文件末尾,可追加写入内容
                        mode----------如果文件为新建,指定权限为mode,如:0777
                    返回值:成功    返回文件描述符
                            失败     返回  -1
            2、read()
                #include <unistd.h>
                ssize_t read(int fildes, void *buf, size_t nbyte);
                    功能:读取描述符为fildes的文件的内容,放入buf指向的内存中,nbyte是期望读取的字节数
                    返回值:成功,返回实际读取的字节数(实际读取的字节数小于或等于nbyte)
                            失败,返回-1
            3、write()
                #include <unistd.h>
                ssize_t write(int fildes, const void *buf, size_t nbyte);
                    功能:把buf指向的内存中的内容,写入描述符为fildes的文件,nbyte是期望写入的字节数
                    返回值:成功,返回实际写入的字节数(实际写入的字节数小于或等于nbyte)
                            失败,返回-1
            4、close()
                #include <unistd.h>
                int close(int fildes);
                    功能:关闭描述符为fildes的文件
                    返回值:成功返回0
                            失败返回-1
            5、lseek()
                #include <unistd.h>
                off_t lseek(int fildes, off_t offset, int whence);
                    功能:定位描述符为fd的文件的读写指针
                    参数:    fd---文件描述符
                            offset---基于基点的偏移量,正数向后偏移,负数向前偏移
                            whence---基点
                                SEEK_SET----文件开头
                                SEEK_END----文件末尾
                                SEEK_CUR----当前位置
                    返回值:成功 返回从文件开头到定位位置的字节数
                            失败 返回-1
            6、ioctl()
                #include <stropts.h>
                int ioctl(int fildes, int request, ... /* arg */);
                    功能:对描述符位fildes文件,进行request操作(一般是驱动中给出命令字(读写之外的其它操作),用户程序通过用的命令字,操控硬件设备)
                    request---->SET_BAUD      //设置波特率
                                REDA_BAUD    //读取波特率
                                FBIOGET_VSCREENINFO //显示屏命令
                    #define 查询屏幕大小的命令 (有固定格式要求的32位整数)
                    fd = open("/dev/fb0",.....)
                    struct struct fb_var_screeninfo var_info;
                    ioctl(fd,FBIOGET_VSCREENINFO,&var_info)
                    struct fb_var_screeninfo {
                                                __u32 xres;                //x方向的像素点个数
                                                __u32 yres;                //y方向的像素点个数
                                                ...
                                                __u32 bits_per_pixel;}    //每个像素点用多少位表示颜色值
            7、fcntl()
                #include <fcntl.h>
                int fcntl(int fildes, int cmd, ...);
                    功能:根据文件描述词来操作文件的特性
                    参数:cmd------>操作命令
                                F_DUPFD :复制文件描述词 。 
                                FD_CLOEXEC :设置close-on-exec标志。如果FD_CLOEXEC位是0,执行execve的过程中,文件保持打开。反之则关闭。 
                                F_GETFD :读取文件描述词标志。 
                                F_SETFD :设置文件描述词标志。 
                                F_GETFL :读取文件状态标志。 
                                F_SETFL :设置文件状态标志。
                                        其中O_RDONLY, O_WRONLY, O_RDWR, O_CREAT,  O_EXCL, O_NOCTTY 和 O_TRUNC不受影响, 可以更改的标志有 O_APPEND,O_ASYNC, O_DIRECT, O_NOATIME 和 O_NONBLOCK。 
                        F_SETLK:在指定的字节范围获取锁(F_RDLCK,F_WRLCK)或者释放锁(F_UNLCK)。如果与另一个进程的锁操作发生冲突,返回 -1并将errno设置为EACCES或EAGAIN。
                    F_SETLKW:行为如同F_SETLK,除了不能获取锁时会睡眠等待外。如果在等待的过程中接收到信号,会立即返回并将errno置为EINTR。 
                                F_GETLK:获取文件锁信息。 
                                F_UNLCK:释放文件锁。
                    返回值:成功 根据不同命令字而不同
                            失败 -1
            8、mmap()
                #include <sys/mman.h>
                void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
                    功能:把描述符为fd的文件,映射到一片内存空间
                    参数:    addr-----指定地址映射,一般设置NULL,表示让系统决定映射的位置
                            length----映射的内存的大小,以字节为单位
                            port----对内能够做何种操作
                                   PROT_EXEC  Pages may be executed.可执行
                                   PROT_READ  Pages may be read.可读
                                   PROT_WRITE Pages may be written.可写
                                   PROT_NONE  Pages may not be accessed.不可访问
                            flags----映射标志
                                MAP_SHARED--共享
                                MAP_PRIVATE---私有
                            offset---一般设置为0
                    返回值     成功---返回内存首地址
                            失败---返回(void *)-1  MAP_FAILED
            9、munmap()
                #include <sys/mman.h>
                int munmap(void *addr, size_t length);
                    功能:取消映射
                    参数:    addr----要取消映射的内存的基地址
                            length---取消映射内存的大小,以字节为单位
            10、dup()\dup2()
                #include <unistd.h>
                int dup(int fildes);
                int dup2(int fildes, int fildes2);
                    功能:复制文件描述符
                    参数:    fildes--->要复制的文件描述符
                            fildes2-->指定的新的文件描述符
                    返回值:成功 返回新的文件描述符
                            失败 -1
            11、显示屏\触摸屏("/dev/fb0","/dev/input/event0")
                相关结构体:
                            struct fb_var_screeninfo {                  //显示屏
                                                __u32 xres;                //x方向的像素点个数
                                                __u32 yres;                //y方向的像素点个数
                                                ...
                                                __u32 bits_per_pixel;}    //每个像素点用多少位表示颜色值
                            struct input_event {
                                                struct timeval time;    -----发生时间
                                                __u16 type;                ----触摸屏事件类型EV_ABS
                                                __u16 code;                ---ABS_X    ABS_Y
                                                __s32 value;}            ----坐标值,触摸屏有触摸动作时,打出x y方向的坐标值    
 标准C库IO
            1、fopen()
                #include <stdio.h>
                FILE *fopen(const char *path, const char *mode);
                    功能:打开或创建文件(获取指定文件的文件指针)
                    参数:path---->指向包含路径的文件名
                          mode---->文件模式标志
                            r          以只读方式打开文件,要求文件必须存在
                            r+         以读/写方式打开文件,要求文件必须存在
                            w          以只写方式打开文件,如果文件不存在会创建新文件,如果存在会将其内容清空
                            w+         以读/写方式打开文件,如果文件不存在会创建新文件,如果存在会将其内容清空
                            a          以只写方式打开文件,文件如果不存在会创建新文件
                                    且文件位置偏移量被自动定位到文件末尾(即以追加方式写数据)
                            a+         以读/写方式打开文件,文件如果不存在会创建新文件
                                    且文件位置偏移量被自动定位到文件末尾(即以追加方式写数据)
                    返回值:成功 返回FILE*
                            失败 返回NULL
            2、fclose()
                #include <stdio.h>
                int fclose(FILE *stream);
                    功能:关闭文件
                    参数:stream ---->要关闭的文件的指针
                    返回值:成功 返回0
                            失败 返回EOF
            3、fread()
                #include <sys/ioctl.h>
                size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
                    功能:从stream对应的文件中读取 size *nmemb个字节,存入ptr指向的内存
                    参数:    ptr------自定义缓冲区指针
                            size-----读取的块的大小
                            nmemb----期望读取到的块数
                            stream---即将被读取数据的文件指针
                    返回值:成功 返回的块数等于期望读到的块数
                            失败 返回的块数小于期望的块数,表示出错或到达文件末尾
            4、fwrite()
                #include <sys/ioctl.h>
                size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
                    功能:把ptr指向的内存中的size *nmemb个字节写入stream对应的文件
                    参数:    ptr------自定义缓冲区指针
                            size-----写入的块的大小
                            nmemb----期望写入的数据块个数
                            stream---即将被写入数据的文件指针
                    返回值:成功 返回的块数等于期望写入的块数
                            失败 返回的块数小于期望的块数
            5、O操作相关函数
                #include <sys/ioctl.h>
                #include <stdio.h>
                int fputc(int c, FILE *stream);---把c(字符)输出到stream对应的文件
                int fputs(const char *s, FILE *stream);----把字符串s输出到stream对应的文件
                int putc(int c, FILE *stream);-----把c输出到stream对应的文件
                int putchar(int c);------只能通过stdout 把c输出到屏幕
                int puts(const char *s);----只能向stdout对应的屏幕输出字符串s
            6、I操作相关函数
                #include <sys/ioctl.h>
                #include <stdio.h>
                int fgetc(FILE *stream);---从stream对应的文件中读取一个字符
                char *fgets(char *s, int size, FILE *stream);----从stream对应的文件中最多读取大小为size-1个字符,存入s指向的位置  注意:读取过程中遇到‘\n’或者EOF停止
                int getc(FILE *stream);---从stream对应的文件中读取一个字符
                char *gets(char *s);-----从自定义缓冲区s中读取数据,由于没有指定s的大小,容易造成溢出导致程序出现段错误
                int getchar(void);------只能通过stdin对应标准输入设备获取字符
            7、feof()/ferror()
                #include <sys/ioctl.h>
                int feof(FILE *stream);
                    功能:测试stream对应的文件读写操作是否到末尾
                    返回值:已到末尾返回非零值(逻辑真值)
                            未到末尾返回零值(逻辑假值)
                int ferror(FILE *stream)    
                    功能:测试stream对应的文件读写操作是否出错
                    返回值:出错返回非零值(逻辑真值)
                            未出错返回零值(逻辑假值)
            8、fseek()/ftell()
                #include <sys/ioctl.h>
                int fseek(FILE *stream,long offset,int whence);----设定指定文件的当前位置偏移量
                    参数:    stream---需要设置位置偏移量的文件指针
                            offset---新位置偏移量相对基准点的偏移
                            whence---基准点(SEEK_SET:文件开头处;SEEK_CUR:当前位置;SEEK_END:文件末尾处)
                    返回值:成功    返回0
                            失败    返回-1
                long ftell(FILE *stream);
                    功能:返回值是stream对应的文件的读写指针位置
            9、缓冲相关
                #include <stdio.h>
                int fflush(FILE *stream);   //刷缓冲满
                int setvbuf(FILE *stream, char *buf, int mode, size_t size);
                    功能:设置stream对应文件的缓冲位置、类型、大小
                    参数:    buf------指向缓冲区
                            mode-----缓冲类型
                                _IONBF unbuffered 不缓冲
                                _IOLBF line buffered  行缓冲
                                _IOFBF fully buffered  满缓冲
                            size-----缓冲区的大小
                    注意:标准输出默认使用行缓冲,普通文件默认使用全缓冲,标准出错不缓冲。
            10、stat()/fstat()/lstat()
                #include <sys/stat.h>
                int stat(const char *restrict path, struct stat *restrict buf);
                int fstat(int fildes, struct stat *buf);0
                int lstat(const char *restrict path, struct stat *restrict buf);
                    功能:获取文件的元数据(类型、权限、大小等)
                    参数:    path--文件路径
                            fildes--文件描述符
                            buf--属性结构体(保存获取到的数据)
                    返回值:成功 0
                            失败 NULL
                    struct stat {
                                   dev_t     st_dev;         /* ID of device containing file 普通文件所在存储器的设备号*/
                                   ino_t     st_ino;         /* inode number 文件索引号*/
                                   mode_t    st_mode;        /* protection 文件类型、文件权限*/
                                   nlink_t   st_nlink;       /* number of hard links */
                                   uid_t     st_uid;         /* user ID of owner 文件所有者的UID*/
                                   gid_t     st_gid;         /* group ID of owner 文件所属组的GID*/
                                   dev_t     st_rdev;        /* device ID (if special file) 特殊文件设备号*/
                                   off_t     st_size;        /* total size, in bytes 文件大小*/
                                   blksize_t st_blksize;     /* blocksize for filesystem I/O */
                                   blkcnt_t  st_blocks;      /* number of 512B blocks allocated */
                                    ....
                                }
        目录检索
            1、mkdir
            #include <sys/stat.h>
            #include <sys/types.h>
            int mkdir(const char *pathname, mode_t mode);
                功能:新建一目录文件,并指定权限
                参数:    pathname---包含路径的文件名
                        mode-----权限
                返回值:成功 0
                        失败 -1
            2、opendir
            #include <sys/types.h>
            #include <dirent.h>
            DIR *opendir(const char *name);
                功能:打开一个目录文件
                返回值:成功返回DIR *
                        失败返回NULL
            3、readdir
            #include <dirent.h>
            struct dirent *readdir(DIR *dirp);
                功能:读取目录文件的内容(目录项)
                struct dirent    {
                                ino_t          d_ino;       /* inode number */
                                off_t          d_off;       /* not an offset; see NOTES */
                                unsigned short d_reclen;    /* length of this record */
                                unsigned char  d_type;      /* type of file; not supported
                                                                  by all filesystem types */
                                char           d_name[256]; /* filename */
                                };
                                其中d_type(文件类型)成员取值如下:
                                DT_BLK      This is a block device.
                                DT_CHR      This is a character device.
                                DT_DIR      This is a directory.
                                DT_FIFO     This is a named pipe (FIFO).
                                DT_LNK      This is a symbolic link.
                                DT_REG      This is a regular file.
                                DT_SOCK     This is a UNIX domain socket.
                                DT_UNKNOWN  The file type is unknown.
                返回值:成功返回struct dirent *
                        出错或到了目录末尾返回NULL
            4、chdir()
            #include <dirent.h>
            int chdir(const char *path);
                功能:切换到path目录下
                返回值:切换成功返回0
                        出错返回-1

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值