• Linux标准IO和文件IO


    一、IO基本概念

    1. ==Linux上一切皆是文件==

    2. 文件的种类

          普通文件: -

          目录文件: d

           符号链接文件:l

           套接字: s

          管道: p

          块设备: b

          字符设备: c

    3. 文件IO与标准IO

       文件描述符: 非负整数,是打开的文件的标识符(编号)   --- 用于文件IO

       文件流:  FILE *   (标准IO)

       进程中有三个文件已打开:

                          文件描述符       文件流

          标准输入 :             0                   stdin

          标准输出 :             1                    stdout

          标准错误输出 :        2                  stderr

    4. C 库

       printf(char *format,  ....);      ---- 把...按照格式输出到标准输出(终端)

       sprintf(char *str, char *format,  ....);  --- 把...按照格式输出到str中

       fprintf(FILE *fp, char *format,  ....);   --- 把...按照格式输出到文件流中

       ```

    5. 错误信息: ==errno== 

       #include

       void perror(const char *s);  --- 打印系统错误信息

           参数: 提示符(一般函数名)

          

       #include

       char *strerror(int errnum);  ---- 返回错误码对应的错误信息

    二、标准IO

    1. 缓冲

    标准IO: 带缓冲的IO

    全缓冲:缓冲区满/fflush(强制刷新)

    行缓存:'\n'/缓冲区满/fflush(强制刷新)

    不缓冲

    int fflush(FILE *stream);  --- 刷新流

    ```

    2.库函数

    1. fopen: 打开文件

    2. fclose:    关闭文件

    1. #include
    2. #include
    3. #include
    4. int main(int argc, char *argv[])
    5. {
    6. FILE *fp=fopen("file_3","w+");
    7. if(NULL==fp)
    8. {
    9. perror("fopoen");
    10. return -1;
    11. }
    12. printf("fopne success!\n");
    13. fclose(fp);
    14. return 0;
    15. }

    3. fgetc

    1. #include
    2. #include
    3. #include
    4. int main(int argc, char *argv[])
    5. {
    6. FILE *fp=fopen("test.c","r");
    7. if(NULL==fp)
    8. {
    9. perror("fopen");
    10. return -1;
    11. }
    12. printf("fopen success!\n");
    13. int ch;
    14. while(1)
    15. {
    16. ch=fgetc(fp); //从fp中读取一个字符,文件末尾为EOF
    17. if(EOF==ch)
    18. break;
    19. fputc(ch,stdout); //向标准输出写入一个字符
    20. }
    21. fclose(fp);
    22. return 0;
    23. }

     读取一个字符,当读取到文件末尾时EOF

    4. fputc

    5. fgets

    1. #include
    2. int main(int argc, char *argv[])
    3. {
    4. char buf[100];
    5. //gets(buf);
    6. //fgets(buf, sizeof(buf), stdin);
    7. //printf("%s", buf);
    8. if (argc < 2)
    9. {
    10. fprintf(stderr, "Usage: %s ", argv[0]);
    11. return -1;
    12. }
    13. FILE *fp = fopen(argv[1], "r");
    14. if (NULL == fp)
    15. {
    16. perror("fopen");
    17. return -1;
    18. }
    19. while (1)
    20. {
    21. if (NULL == fgets(buf, sizeof(buf), fp))
    22. break;
    23. fputs(buf, stdout);
    24. }
    25. fclose(fp);
    26. return 0;
    27. }

       char *fgets(char *s, int size, FILE *stream); //从流中读取size-1个字符装在s中

       注:fgets用于读取一行,遇'\n'结束,且=='\n'==也会被装在s中

            fgets最多只能输入size-1个字符,末尾装null

            当读取到文件末尾时返回NULL

    6. fputs

    7. fseek: 定位

       #include

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

             参数: stream: 文件流

                offset: 偏移量

                whence: 基准(SEEK_SET文件头, SEEK_CUR当前位置S, SEEK_END文件尾)

             返回值:

               成功: 0

               失败: -1, 并设置errno

           long ftell(FILE *stream);    //获取当前流的偏移量

           void rewind(FILE *stream);  //偏移到文件头位置

    三、文件IO

    1、文件描述符

    2、open:

    #include

    #include

    #include

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

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

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. int main(int argc, char *argv[])
    9. {
    10. //int fd=open("1.txt",O_RDONLY); //"r"
    11. int fd=open("1.txt",O_WRONLY|O_CREAT|O_TRUNC,0664);
    12. if(fd<0)
    13. {
    14. perror("open");
    15. return -1;
    16. }
    17. printf("fd=%d\n",fd);
    18. close(fd);
    19. return 0;
    20. }

    参数:

       pathname: 路径 + 文件名

        flags: 打开方式

          O_RDONLY:  只读打开

              O_WRONLY:  只写打开

              O_RDWR: 可读写打开

              O_CREAT: 当文件不存在时创建文件,此时需要第三个参数mode

              O_TRUNC: 当文件存在时清空文件内容

              O_APPEND: 追加打开

       mode: 创建的文件的权限,一般0664

    返回值:

      成功: 文件描述符(非负整数)

        失败: -1, 并设置errno

    3、close: 关闭文件描述符

       #include

       int close(int fd);  //参数: 文件描述符

    4、read/write

    #include

    ssize_t read(int fd, void *buf, size_t count); //从fd文件中读取count字节放在buf中

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. int main(int argc, char *argv[])
    9. {
    10. int fd=open("./1.txt",O_RDONLY);
    11. if(fd<0)
    12. {
    13. perror("open");
    14. return -1;
    15. }
    16. lseek(fd,100,SEEK_SET); //lseek函数,从文件头开始偏移量100
    17. char buf[64];
    18. int ret;
    19. while(1)
    20. {
    21. ret=read(fd,buf,sizeof(buf));
    22. if(ret<0)
    23. {
    24. perror("read");
    25. break;
    26. }
    27. else if(0==ret)
    28. {
    29. printf("read file end!\n");
    30. break;
    31. }
    32. if(0>write(1,buf,ret))//向标准输出写入数据
    33. {
    34. perror("write");
    35. break;
    36. }
    37. }
    38. close(fd);
    39. return 0;
    40. }

    参数:

          fd --- 文件描述符

        buf --- 内存中用于存放读取数据的空间首地址

        count --- 想要读取的字节数

    返回值:

        成功:成功读取的字节数

           0(当读取到文件末尾时)

       失败:-1, 并设置errno

    #include

    ssize_t write(int fd, const void *buf, size_t count); //把buf中的count字节数据写入文件fd中去

    参数:

          fd --- 文件描述符

        buf --- 想要写入数据的首地址

        count --- 想要写入的字节数

    返回值:

        成功:成功写入的字节数

       失败:-1, 并设置errno

    ```

    5、lseek: 定位

    off_t lseek(int fd, off_t offset, int whence);  //定位

       参数:

         fd: 文件描述符

         offset: 偏移量

         whence: 基准(SEEK_SET文件头, SEEK_CUR当前位置, SEEK_END文件尾)

       返回值:

         成功: 当前的偏移量

         失败: -1, 并设置errno

    四、文件属性和目录

    1、文件属性

    #include

    #include

    #include

    int stat(const char *pathname, struct stat *statbuf);  //获取文件属性

    struct stat {

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

        ino_t     st_ino;         /* Inode number */

        mode_t    st_mode;        /* File type and mode */

        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;     /* Block size for filesystem I/O */

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

    };

    注:使用下面的宏函数可以判断文件的类型:参数为struct stat的st_mode成员

    S_ISREG(st_mode);  --- 判断是否是普通文件

    S_ISDIR(st_mode)  directory?

    S_ISCHR(st_mode)  character device?

    S_ISBLK(st_mode)  block device?

    S_ISFIFO(st_mode) FIFO (named pipe)?

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

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

    ```

    2、目录

    int system(char *commad);  //执行shell命令

    int chdir(char *path); //切换当前的工作路径,类似与cd命令

    参数:

        path: 要切换的路径

    返回值:

          成功: 0

        失败: -1, 并设置errno

    #include

    #include

    DIR *opendir(const char *name);   //打开目录

    参数:

        name: 目录名

    返回值:

        成功:目录流指针

        失败:NULL, 并设置errno

    int closedir(DIR *dirp);   //关闭目录

    参数:

        dirp: 目录流指针

    struct dirent *readdir(DIR *dirp);  //读取目录

    struct dirent {

        ino_t          d_ino;       /* Inode number */

        off_t          d_off;       /* Not an offset; see below */

        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]; /* Null-terminated filename */

    };

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. int main(int argc, char *argv[])
    7. {
    8. DIR *dirp=opendir(".");//打开目录
    9. if(NULL==dirp)
    10. {
    11. perror("dirp");
    12. return -1;
    13. }
    14. struct dirent *p=NULL;
    15. while(1)
    16. {
    17. p=readdir(dirp);//读取目录下的内容
    18. if(NULL==p)
    19. {
    20. break;
    21. }
    22. if('.'==p->d_name[0])//跳过所有的隐藏文件
    23. continue;
    24. printf("name:%s\n",p->d_name);//关闭目录
    25. }
    26. closedir(dirp);//
    27. return 0;
    28. }

    参数: 目录流指针

    返回值:

       读取的文件dirent结构体指针

        当读取到目录流结束时,返回NULL

    ```

    五、静态库与动态库

    1、库的概念

    库的好处:

    (1)把常用的复杂的功能封装成库,用户只需要使用库,不需要理解内部原理

       2库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议

    静态库与动态库优缺点:

         (1)静态库与动态库链接进目标代码的时机不同,静态库在编译时期,动态库在执行时期

         (2)静态库占空间大,但是移植方便

         (3)动态库占空间小

    2、静态库的制作与使用

    gcc  -c 源文件      ---- 生成目标文件.o

    ar crs  lib库名.a  目标文件    ---- 把目标文件生成静态库文件

       注: 静态库的库前缀lib,后缀.a

    gcc 源文件 -L库路径  -l库名    --- 静态库的使用

    3、动态库的制作与使用

    动态库的制作

    gcc -fPIC -Wall -c 源文件  ---- 生成与地址无关的目标文件.o

    gcc -shared -o libmytest.so 目标文件  --- 把目标文生成动态库文件

    注: 动态库的库前缀lib,后缀.so

    动态库的使用下面三种办法:

    编译:gcc  源文件 -L库路径  -l库名

    为了让执行程序顺利找到动态库,有三种方法 :

    (1)把库拷贝到/usr/lib和/lib目录下。

    (2)在LD_LIBRARY_PATH环境变量中加上库所在路径。

        export LD_LIBRARY_PATH=库路径

    (3) 添加/etc/ld.so.conf.d/*.conf文件,把库所在的路径加到文件末尾,并执行ldconfig刷新。这样,加入的目录下的所有库文件都可见。

  • 相关阅读:
    安克创新音频算法工程师(应届生)招聘
    【无标题】
    Canal增量订阅MySQL数据同步工具
    一文带你看懂Java中的Lock锁底层AQS到底是如何实现的
    Datawhale ChatGPT基础科普
    Go语言 包管理
    数据采集之:巧用布隆过滤器提取数据摘要
    【js】call()、apply()、bind() 的用法
    灵魂之问:机器人编程学习的是什么?/机器人课与科学课/机器人课和编程课/乐高机器人学的是什么?
    数字工厂中的SCADA(数据采集与监控系统)
  • 原文地址:https://blog.csdn.net/qq_63626307/article/details/126292782