IO笔记

课程概览

===============

    1.学习方法:学接口函数(返回值,功能,形参)

    2.系统IO相关的函数

      标准IO相关的函数

      目录操作相关的函数

系统IO函数

==============

    IO:input  output文件的输入和输出

          嵌入式中有大量的硬件设备(液晶屏,触摸屏,键盘)

          linux中一切都是文件: /dev

          open()  read()  write  close  lseek  stat    dup  dup2

    (1)文件的打开或者新建

      #include

      #include

      #include

          int open(const char *pathname, int flags);

                返回值:成功返回文件描述符或者翻译成文件的句柄(重点,替身)

                        专业理解:文件描述符就是数组的下标(系统中定义一个专门存放打开文件属性信息的结构体数组)

                        非专业理解:文件描述符就是替身

                        失败  -1

                  参数:pathname --》你要打开、新建的文件的路径名

                        flags --》O_RDONLY,  O_WRONLY,  or  O_RDWR.  宏定义

                                  用什么权限打开文件

              int fd=open("/home/gec/1.txt",O_RDWR);

          int open(const char *pathname, int flags, mode_t mode); //新建文件的同时可以设置文件的权限

                  参数:mode --》设置权限的,用八进制的数字表示权限

                        flags --》O_CREAT 新建文件

                                  O_EXCL  配合O_CREAT一起使用,表示如果新建的文件已经存在就返回-1并退出

                                  O_TRUNC 配合O_CREAT一起使用,表示如果新建的文件已经存在就清空覆盖掉原来的文件

                        open("/home/gec/new.txt",O_CREAT,0777);


          总结:linux中只要函数参数有多个宏定义让你选择

                你如果要使用多个宏,都是用按位或连接起来


系统IO

=================

        在共享里面用chmod修改权限是不准确的(windows跟linux公用的环境,修改权限,创建软链接都会有问题)

        rwxrwxrwx 1 root root  33 Jan 13 22:08 1.txt

        touch命令:

              新建文件,但是无法打开文件             

        /usr/src/linux-headers-3.5.0-23-generic/include/linux/sched.h的第1394行定义结构体指针,专门用来指向打开成功的文件信息(结构体数组)

      (2)读取文件内容

                fd=open("1.txt")  文件描述符和文件名本身之间一一对应的映射关系

                typedef 给常见的类型换了新名字,例如mode_t  size_t  ssize_t  off_t

                #include

                ssize_t read(int fd, void *buf, size_t count);

                      返回值:成功读取的字节数  失败  -1

                              文件读取完毕返回0

                              fd --》文件或者硬件设备的文件描述符

                              buf --》可以接收任意类型指针作为实参,存放你读取到的文件内容

                              count --》你打算读取多少字节的数据

      (3)写入文件

                #include

                ssize_t write(int fd, const void *buf, size_t count);

                      返回值:count写多少,返回值就是多少  失败  -1

                              注意问题:count不要随便乱写

      (4)文件的关闭

              int close(int fd);

      (5)设置文件读写偏移(设置光标位置)

              off_t lseek(int fildes, off_t offset, int whence);

                      返回值:当前光标距离文件开头的字节数    失败  -1

                        参数:fildes --》你要设置偏移的文件的文件描述符

                              offset --》你打算偏移多少字节

                              whence --》SEEK_SET -->起始位置

                                          SEEK_CUR -->当前位置

                                          SEEK_END -->文件末尾

                        例如:lseek(fd,0,SEEK_END); 返回值就是文件的大小,记得求出大小以后,重新将光标移动回起始位置

                              lseek(fd,-5,SEEK_END);         

练习:

    1.拷贝文件 -->通过主函数传参拷贝一个文件

          ./main  1.txt  2.txt 

              1.txt本来就有(字节数要求多一点,例如拷贝我们的某一天的笔记)

              2.txt没有

    2.open("1.txt") ,打印文件描述符

      open("2.txt") ,打印文件描述符

      关闭1.txt

      open("3.txt") ,打印文件描述符

    3. lseek(fd,-5,SEEK_SET);

      lseek(fd,-5,SEEK_CUR);

    4. 要求将文件最后面十个字节的内容,以及倒数第50到60这十个字节的数据拷贝到另外一个文件中

            ./main  1.txt

    5. 在开发板上显示bmp格式的图片

        bmp格式图片特点:

                1.每个像素点占3个字节

                2.bmp格式是微软公司发明的,存储的时候颜色值颠倒BGR

                3.存储的时候上下也是颠倒的

        机器视觉 -->图像处理 opencv  openGL


系统IO

=================

      vim新建文件,会有隐藏字符,你可以在/etc/vim/vimrc配置文件中,加上set list这句话,显示隐藏的字符

      (6)获取文件属性信息(比如:文件的权限,文件的大小)

      #include

      #include

      #include

      int stat(const char *path, struct stat *buf);  //不能够判断软链接

      int lstat(const char *path, struct stat *buf);  //能够判断软链接

                  返回值:成功  0    失败  -1

                    参数:path --》文件的路径名

                          buf --》存放你获取到的文件的属性信息

          struct stat {

              dev_t    st_dev;    /* ID of device containing file */

              ino_t    st_ino;    /* inode number */  linux将目录中所有的内容用类似链表的存储结构,每个节点都有一个编号

              mode_t    st_mode;    /* protection */  存放文件的权限信息,文件类型信息(重点)

              nlink_t  st_nlink;  /* number of hard links */

              uid_t    st_uid;    /* user ID of owner */

              gid_t    st_gid;    /* group ID of owner */

              dev_t    st_rdev;    /* device ID (if special file) */  字符设备或者块设备

              off_t    st_size;    /* total size, in bytes */  文件大小

              blksize_t st_blksize; /* blocksize for file system I/O */

              blkcnt_t  st_blocks;  /* number of 512B blocks allocated */

              time_t    st_atime;  /* time of last access */    最后访问时间

              time_t    st_mtime;  /* time of last modification */  修改时间

              time_t    st_ctime;  /* time of last status change */ 状态改变时间

          };

          S_IRWXU    00700    mask for file owner permissions

          S_IRUSR    00400    owner has read permission

          S_IWUSR    00200    owner has write permission

          S_IXUSR    00100    owner has execute permission

          S_IRWXG    00070    mask for group permissions

          S_IRGRP    00040    group has read permission

          S_IWGRP    00020    group has write permission

          S_IXGRP    00010    group has execute permission

          S_IRWXO    00007    mask for permissions for others (not in group)

          S_IROTH    00004    others have read permission

          S_IWOTH    00002    others have write permission

          S_IXOTH    00001    others have execute permission

          S_ISREG(m)  is it a regular file?

          S_ISDIR(m)  directory?

          S_ISCHR(m)  character device?

          S_ISBLK(m)  block device?

          S_ISFIFO(m) FIFO (named pipe)?

          S_ISLNK(m)  symbolic link? (Not in POSIX.1-1996.)

          S_ISSOCK(m) socket? (Not in POSIX.1-1996.)

      (7)文件重定向

            标准输出:lcd  printf打印的内容

            标准错误输出:lcd  perror打印

            int dup(int fildes); //给旧的文件描述符,分配新的文件描述符

                  返回值:新的文件描述符  失败  -1

                    参数:fildes --》原本旧的的文件描述符

            int dup2(int fildes, int fildes2);


      (8)错误码

            原理:linux中定义一个全局变量errno,保存了linux系统中所有常见的错误类型

                  linux头文件中将所有的出错定义成了宏,errno保存某个出错的宏定义

                /usr/include/asm-generic/errno.h定义了一部分错误的宏

            #include

            #include

              void perror(const char *s); //将错误的原因也打印出来

                      参数:s --》打印信息


      (9)修改权限

            int chmod(const char *path, mode_t mode);

练习:

      主函数传参传递路径

            检查参数个数 --》不符合要求退出,让用户传参

            检查文件类型 --》普通文件,要求获取文件大小,并判断文件的权限是不是当前用户可读可写

                              如果权限不符合要求使用chmod()函数修改权限为可读可写,然后拷贝

                              目录,退出程序,提示用户,文件类型不符合要求

标准IO

=================

      标准IO和系统IO

            主要区别:系统IO open  read  write  close  不带读写缓冲

                      标准IO fopen  fread  fwrite  fclose  带缓冲

      (1)打开文件

            FILE *fopen(const char *path, const char *mode);

                  返回值:成功返回FILE类型的指针用来存放文件的信息

                          失败  NULL

                    参数:mode --》r  只读的方式打开

                                  r+  可读可写的方式打开

                                  w  如果文件不存在,可以新建

                                      如果文件存在,清空  可写的方式打开

                                  w+  如果文件不存在,可以新建

                                      如果文件存在,清空  可读可写的方式打开

                                  a  追加的方式打开文件,不存在,新建

                                  a+  追加的方式打开文件,不存在,新建

      (2)文件的读写

            ssize_t read(int fd, void *buf, size_t count);

                  read(fd,buf,100);

                  fread(buf,10,10,myfile);

                  fread(buf,25,4,myfile);

                  fread(buf,100,1,myfile);

            size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

                      以数据块为单位读

                      返回值:重点 成功读取到的完整的数据块的个数 

                        参数:size --》每个数据块的大小  字节 

                              nmemb --》你打算读取多少个数据块

            size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

                      返回值:重点 在没有超出缓冲区大小的情况下 nmemb写多少,返回值就是多少

标准IO

================

      硬件的驱动:用系统IO操作

      读写一个普通文件:建议你用标准IO,带缓冲速度快

      (4)关闭

            int fclose(FILE *fp);

      (5)字符串的拼接和拆分

            sprintf() //字符串的拼接,可以将任意类型的数据拼接成字符串(*****重点)

                int sprintf(char *str, const char *format, ...); //可变参数函数

                          参数:str --》存放拼接得到的字符串

                                format --》你想按照什么格式去拼接字符串

                          注意:str大小一定要足够存放结果

            sscanf() //字符串拆分

                int sscanf(const char *str, const char *format, ...);

                          参数:str --》你要拆分的字符串

                                format --》你打算按照什么格式拆分

      (6)刷新缓冲区,区分系统IO(不带缓冲区)和标准IO(f开头的那些函数,带缓冲区)

            int fflush(FILE *stream);


      (7)求缓冲区大小

            系统中/usr/include/stdio.h  第49行类型重定义了FILE

                  /usr/include/libio.h  第273行就有结构体的完整定义

            linux中将缓冲分为三种:不带缓冲,全缓冲,行缓冲

                  全缓冲:等待缓冲去填满,才进行IO操作,普通文件

                    A 当缓冲区被填满时,立即刷新

                    B 当调用fflush( )时,立即刷新

                    C 当调用setbuf( )/setvbuf( )时,立即刷新

                    D 当进程正常关闭时,立即刷新(暂时不管)

                      D.1 在main函数中return

                      D.2 调用exit( )/_exit( )/_Exit( )

                      D.3 在最后一条线程中调用pthread_exit( )

                    E 当调用fclose( )时,立即刷新

                  行缓冲:等待一行结束 \n,进行IO操作,或者行缓冲区满了,刷新,标准输出(屏幕),标准IO

                    A 当缓冲区被填满时,立即刷新

                    B 当调用fflush( )时,立即刷新

                    C 当调用setbuf( )/setvbuf( )时,立即刷新

                    D 当进程正常关闭时,立即刷新

                      D.1 在main函数中return

                      D.2 调用exit( )/_exit( )/_Exit( )

                      D.3 在最后一条线程中调用pthread_exit( )

                    E 当调用fclose( )时,立即刷新

                    F 当遇到'\n'时,立即刷新

          (8)设置文件读写的偏移

              int fseek(FILE *stream, long offset, int whence);

              long ftell(FILE *stream); //返回文件当前位置距离文件开头的字节数

              void rewind(FILE *stream); //等价于fseek(filep,0,SEEK_SET);

                    C语言:long整型 long m=12;

                                    long m=12L;


          (9)fgets()  fputs()  gets()  puts()  getchar()  putchar() getc()  putc()

                第一组:fgets()  fputs()

                    总结:fgets(buf,size,filep);

                            size没有超出文件一行的大小,buf中最后面填充'\0'

                            size超过了文件一行的大小,buf中最后面将回车(windows上\r\n)以及'\0'补充在后面

                                                                      (linux上\n)

                    char *fgets(char *s, int size, FILE *stream);  //读取一行数据                 

                            返回值:读取到字符串的首地址  失败  NULL

                              参数:s --》存放读取到的字符串

                    int fputs(const char *s, FILE *stream); //写入一行数据

              第二组:gets()  puts()

                    char *gets(char *s); //只能从键盘读取字符串

                    int puts(const char *s); //只能写入到标准输出(液晶屏)

              第三组:getchar()  putchar()

                    int getchar(void);

                    int putchar(int c); //只能是写入一个字符到lcd

                          返回值:对应字符的ASCII值

                            参数:c --》你要写入的字符的ASCII值

              第四组:getc()  putc()

                    int getc(FILE *stream);

                        getc(stdin); 从键盘读取一个字符,返回字符的ASCII码值

                        getc(filep); 从filep代表的文件中读取一个字符

                    int putc(int c, FILE *stream);

                        putc('y',stdout); //将y打印在屏幕上

                        putc('y',filep); //将字符y写入到filep代表的文件中

你可能感兴趣的:(IO笔记)