I/O进线程基础知识1

文章详细介绍了Linux系统中的IO操作,包括标准I/O和文件I/O的区别,常用的标准I/O函数如fopen、fgets、fputc等的使用,以及文件描述符的概念和文件操作函数open、read、write。此外,还提到了目录操作函数opendir、readdir和文件信息获取函数stat。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用时注意头文件的添加,不知道的可以用man来查看所需头文件;

一.IO以及文件:

        IO分为两种:

        1.标准I/O

                c库函数:在系统调用之上封装的接口,一个c库可以封装多个系统调用函数;

              特点:  1.增加可移植性,复用性;2.提高效率

        2.文件I/O

                Linux系统提供的,在我们使用到一些底层功能时,我们不能自己进行访问,而是向操作系统发出请求。

特点:    

   1. 不带缓冲区
   2. 操作系统直接提供的函数接口
   3. 调用系统调用是很耗费资源的

二.常用的标准I/O函数:

文件的打开:

调用文件,通过fopen函数来实现,FILE *---称作流指针

FILE *fp = fopen(“文件的路径”,“如何打开文件”);

打开文件方式:r---只读(文件必须存在)        r+---可读可写(文件必须存在)

                           w---可读(文件不存在,会主动创建,如果存在则清空文件)

                           w+可读可写(文件不存在,会主动创建,如果存在则清空文件)

                        a----读(文件存在直接在末尾追加,不存在就创建)

                        a+----读写(文件存在直接在末尾追加,不存在就创建)

出错的处理:

perror(“字符串”);参数就是字符串

stdin:标准输入流

stdout:标准输出流

stderr:标准错误流

3.fgets函数和fgetc函数

        fgets:从文件中读入字符串;fgetc:从文件读入一个字符

1.fgets--char *Fgets (char * a,sizeof(a),FILE *fp); //第一个位置为要输入到那里,容器所在位置;第二个为容器的内存大小;第三个就是要从哪个文件输入(流指针);

char str[32] = {0};
fgets(str,sizeof(str),stdin);    //从标准输入流中得倒字符串
//fgetc同理

fputs(str,stdout);    //将字符串输出到标准输出流中

4fputs函数和fputc函数:

fputc(单个字节,FILE *fp);//第一个位置就是要输出到字符,第二个位置为要输出到的位置,要输出到文件时用流指针

Fputs(字符串,FILE *fp//第一个位置就是要输出到字符串,第二个位置为要输出到的位置,要输出到文件时同样用流指针

5.缓冲区:

有三种:行缓冲,全缓冲,无缓冲;

1.printf,stdin,stdout是行缓冲

        行缓冲的大小为1024byte

        行缓冲的输出条件:1.行缓冲存满了,或者遇到\n时就将缓冲区中的内容输出

                                                2.fflush()强制刷行

                                                3.return以及exit程序结束时

                                                4.fclose()文件关闭时输出

2.全缓冲:

用fopen打开文件后返回的流指针,流指针就为全缓冲,大小为4*1024;

全缓冲的输出条件:

        1.缓冲存满了

              2.fflush()强制刷行

                 3.return以及exit程序结束时

                    4.fclose()文件关闭时输出

3.无缓冲:

        stderr,输入后直接输出

6. fseek函数和lseek函数

 1. int fseek(FILE *stream,long offset,int where);

        位置1:流指针

        位置2:偏移量

        位置3:基点

偏移量为>0的数:向后移,<0: 向前移

where的位置可以使用以下三个:偏移量就不需要了,置为零

        1 SEEK_SET:使文件指针指向文件开头

        2 SEEK_END:使文件指针指向文件末尾

        3 SEEK_CUR:文件的当前位置

2.lseek(FILE *stream, 偏移量(>0 : 向后  ; <0:向前) , SEEK_SET/SEEK_END/SEEK_CUR);

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

其他操作文件指针的函数:

        void rewind(FILE *stream);        //文件指针回文件开头

7. fread和fwrite

fgets() 有局限性,每次最多只能从文件中读取一行内容,因为 fgets() 遇到换行符就结束读取。如果希望读取多行内容,需要使用 fread() 函数;相应地写入函数为 fwrite()。

        1.fread 读取函数

                fread(存放读取到的数据到内存地址,字节数,块数,流指针);//从流指针指向的文件中读取数据,写入到内存中

        2.fwrite 写入函数

                fwrite(要读取数据的内存地址,字节数,块数,流指针);//从内存中读取数据,写入到流指针指向的文件中

8.printf相关函数

    组装数据

    fprintf( 流指针, "%d-%d-%d", 2023, 2, 16 );  //放在流指针代表的文件中

    sprintf( 内存地址, "%d-%d-%d", 2023, 2, 16 );  //放在内存中

提取数据    

    sscanf(内存地址,"%d-%d-%d", &a, &b, &b);         //从内存地址中提取数据

    fscanf(流指针,"%d-%d-%d", &a, &b, &b);              //从文件中提取内容数据

9.时间相关的函数

        localtime的用法:

                time_t t;

                int get_time = time(NULL);        //or         int get_time = time(&t);        //返回从1970-1-1 0:0:0开始到现在的秒数

                struct tm *time= localtime(&t);        //将从1970-1-1 0:0:0开始到现在的秒数转化成日历

结构体tm的参数:

struct tm {

   int tm_sec;    /* 秒 (0-60) */

   int tm_min;    /* 分钟 (0-59) */

   int tm_hour;   /* 小时 (0-23) */

   int tm_mday;   /* 天 (1-31) */

   int tm_mon;    /* 月份(0-11) */        要使用打印时间月份记得加一: time->tm_mon+1;

   int tm_year;   /* 年份- 1900 */         要使用打印时间年份记得加1900: time->tm_mon+1900;

};

三. 文件IO

1 文件描述符:

        当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符,作为该文件的索引值,文件描述符在形式上是一个顺序分配的非负整数;一般最大打开的文件描述符数量为1024(0~1023);

而有三个默认的文件描述符:

stdin : 0;                 stdout   :1;                stderr:2;                

FILE * fdopen(int fd,打开方式);        //fd为文件描述符

2 常用的文件IO函数

        1. open函数

文件存在:int open(文件路径,打开方式);        //打开成功,返回文件描述符,不成功返回-1;文件路径可以直接用文件描述符来替换;

文件不存在:int open(文件路径,打开方式,文件权限(0664/0666));

打开方式:

O_RDONLY:只读        O_WRONLY:可写

O_RDWR:读写         O_APPEND:追加

O_TRUNC:清零        O_CREAT:创建 

        2. read函数和write函数

1.read()从文件中读取数据

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

功能:从文件中读取count字节的数据到内存

参数:

   fd: 文件描述符

   buf: 内存地址

count: 读取的字节数 

2.write()向打开的文件写入数据

原型:ssize_t  write(int  fd,  const void *buf, size_t count);        //参数以及用法都和read函数差不多

3. close()使用完文件后要关闭;int close(int fd);同fclose();

四.目录操作函数

1.DIR *opendir(const char *name);

功能:打开目录

参数:        name: 目录的路径名

返回值:成功: DIR *  ;      失败: NULL

DIR *p_dir = opendir(“要打开的目录的地址”);

 2.struct dirent *readdir(DIR *dirp);

功能:读取目录信息

参数: dirp: opendir的返回值

返回值:

   成功: struct dirent *

   失败: NULL(一直遍历,直到遍历目录完成返回NULL)

struct dirent *re_dir = readdir(p_dir);

 struct dirent
{
  ino_t    d_ino;       /* inode number 索引节点号 */
     off_t d_off;         /* offset to this dirent 在目录文件中的偏移 */
     unsigned short d_reclen;         /* length of this d_name 文件名长 */
     unsigned char d_type;             /* the type of d_name 文件类型 */
     char d_name [256];         /* file name (null-terminated) 文件名,最长255字符 */
 }

3.        int closedir(DIR *dirp);

参数: dirp: opendir的返回值

4文件信息函数

struct stat mybuf;        //定义一个结构体变量mybuf;

int stat(const char *path, struct stat *buf);

功能:得到文件的属性

参数:

 path:文件路径名

 buf: &mybuf

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;  所属用户ID   /* user ID of owner */ 

gid_t     st_gid;  所属组ID   /* 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 filesystem 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 */

};

chdir(路径);改变工作目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值