Linux5:文件操作(标准IO,文件IO):打开,创建,读写操作,标准IO和文件IO的区别

    科技2025-04-22  11

    文件操作(标准I/O,文件I/O):打开,创建,读写操作,标准I/O和文件I/O的区别

    Linux系统下一切皆文件。

    1.标准I/O(缓冲区文件操作)

    接口:

    类型 ANSI C标准文件操作管理

    文件描述:

    认识缓冲区

    一块内存区,在输入输出设备和CPU间,用来缓存数据。

    读写操作都要经过缓冲区满足一定条件(遇到’\n’通过相关函数)后进行真正的写入和读出标准输入/输出流:

    程序开始运行时,会有3个默认打开的文件标识符 0:标准输入:stdin:STDIN_FILENO 系统分配为键盘 1:标准输出:stdout: STDOUT_FILENO 系统分配为显示器 2:标准错误:stderr: STERROR_FILONO 系统分配为显示器 fflush()//清理缓冲区的函数 fflush(stdin) ffush(stdout)

    FILE指针 定义 系统为打开文件建立的文件结构体,打开时返回来一个指针,程序通过指针获得文件信息,访问文件,关闭后,文件结构体被释放

    ANSI c描述一个打开的文件,定义stdio.h 形式 struct _iobuf { char *_ptr;//当前缓冲区内容指针 int _cnt;//缓冲区还有多少个字符 char *_base;//缓冲区的起始地址 int _flag;//文件流的状态,是否错误或者结束 int _file;//文件描述符 int _charbuf;//双字节缓冲,缓冲2个字节 int _bufsiz;//缓冲区大小 char *_tmpfname;//临时文件名 }; typedef struct _iobuf FILE;

    打开关闭 API

    fopen 原型 FILE * fopen(const char * path,const char * mode); 功能 打开由path指定的一个文件 头文件 #include<stdio.h> 参数 path:带路径的文件名 mode打开方式 r 打开只读文件,该文件必须存在 r+ 打开可读写的文件,该文件必须存在 w 打开只写文件,若文件存在则文件长度清为0,即会擦些文件以 前内容。若文件不存在则建立该文件。 w+ 打开可读写文件,若文件存在则文件长度清为0,即会擦些文件 以前内容。若文件不存在则建立该文件。 a 以附加的方式打开只写文件。若文件不存在,则会建立该文件, 如果文件存在,写入的数据会被加到文件尾,即文件原先的内容 会被保留。 a+ 以附加方式打开可读写的文件。若文件不存在,则会建立该文 件,如果文件存在,写入的数据会被加到文件尾后,即文件原先 的内容会被保留。 返回值 成功,返回操作文件的指针 失败,返回NULL fclose 原型 int fclose(FILE *fp) 功能 关闭文件指针,释放资源 参数 fp: fopen返回的文件指针 返回值 成功返回 0 失败返回 -1

    注意事项: 有没有这个文件 你要进行的操作

    代码演示:

    #include <stdio.h> int main(int argc,char *argv[]) { FILE *fp=NULL; fp = fopen("hello.txt","r"); if(fp == NULL) { perror("fopen");//打印错误原因 return -1; } printf("打开文件成功\n"); fclose(fp); return 0; }

    单个字符读写 API

    fputc 原型 int fputc(int c, FILE *stream) 头文件 #include <stdio.h> 功能 写一个字符到文件中 参数 c:要写入的字符 stream:文件指针(要有可写权限) 返回值 成功:字符c 失败: EOF fgetc 原型 int fgetc(FILE *stream); 头文件 #include <stdio.h> 功能 从文件中读一个字符 返回值 成功:返回读出的字符 失败: EOF feof 原型 int feof(FILE *stream); 头文件 include <stdio.h> 功能 检查文件是否读取结束 参数 stream:指向待检查文件的指针 返回值 文件未结束: 0 文件已结束: 1

    代码演示:

    #include <stdio.h> int main(int argc,char *argv[]) { FILE *fp=NULL; char ch; fp = fopen("hello.txt","w+"); if(fp == NULL) { perror("fopen"); return -1; } printf("打开文件成功\n"); while(ch != '#') { fputc(ch,fp); ch = getchar(); } fclose(fp);//关闭后重新打开,移动光标 fp = fopen("hello.txt","r");//不能使用w,w+ if(fp == NULL) { perror("fopen"); return -1; } printf("打开文件成功\n");//重新打开,移动光标 ch = fgetc(fp); while(!feof(fp))//文件未结束时候为0 { putchar(ch); ch = fgetc(fp); } fclose(fp); return 0; }

    运行结果:

    字符串读写

    fgets 原型 char * fgets(char * s, int size, FILE * fp); 头文件 #include <stdio.h> 功能 从fp指向的文件中读出一行(最多size-1个字符) 直到出现换行字符、读到文件尾或是已读了size-1 个字符为止,写入s指向的缓冲区。 参数 s 保存读取到的字符 size 要读取的字符的个数 fp 为文件流指针 返回值 取成功,返回读取到的字符串,失败NULL fputs 原型 int fputs(const char *s, FILE *fp) 功能:将字符串s写入fp指向的文件中 s: 要写入文件的缓冲区指针 fp:要写入的目标文件的流指针

    代码演示:

    #include <stdio.h> #include <string.h> int main(int argc,char *argv[]) { FILE *fp=NULL; char w_buf[12] = "hello world";//12个 char r_buf[12]; memset(r_buf,0,sizeof(r_buf)); fp = fopen("hello.txt","w+");//w不行,为只写没有读功能,清空 if(fp == NULL) { perror("fopen"); return -1; } printf("打开文件成功\n"); fputs(w_buf,fp);//写入 rewind(fp); fgets(r_buf,12,fp);//读取 printf("r_buf:%s\n",r_buf);//打印读取到的内容 fclose(fp); return 0; }

    运行结果:

    块读块写:

    fread 原型 size_t fread(void *ptr, size_t size, size_t nmemb, FILE fp); 头文件 #include <stdio.h> 功能 读文件 参数 ptr: 要读入的缓冲区指针, 提前申请好的 size: 要读出的信息单元的大小 一般情况下, size设为1 nmemb:要读出的信息单元的个数, size nmemb不大于ptr大小 fp: 要读的文件指针, 提前用fopen打开的 返回值 成功:读取的信息单元的个数 失败: EOF 一般情况下, size设为1, nmemb设为想要读取 的字节数或者ptr指向buf 的大小,返回值为实际读 写的字节数。 fwrite 原型 size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE fp); 头文件 #include <stdio.h> 功能 写文件 参数 ptr: 要写入的缓冲区指针, 提前申请好的 size: 要写入的信息单元的大小 一般情况下, size设为1 nmemb:要写入的信息单元的个数, size nmemb不大于ptr大小 fp: 要写的文件指针, 提前用fopen打开的 返回值 成功:写入的信息单元的个数 失败: EOF 一般情况下, size设为1, nmemb设为想要读取 的字节数或者ptr指向buf 的大小,返回值为实际读 写的字节数。

    代码演示:

    #include <stdio.h> #include <string.h> int main(int argc,char *argv[]) { FILE *fp=NULL; int w=0,r=0; char w_buf[12] = "hello world"; char r_buf[12]; memset(r_buf,0,sizeof(r_buf)); fp = fopen("hello.txt","w+");//采样w+,可读写 if(fp == NULL) { perror("fopen"); return -1; } printf("打开文件成功\n"); w = fwrite(w_buf,1,sizeof(w_buf),fp);//返回写入的个数 if(w < 12) { perror("fwrite");//为啥失败了 return -1; } printf("w = %d\n",w); rewind(fp);//移动光标 r = fread(r_buf,1,sizeof(r_buf),fp);//返回读取个数 if(r < 12) { perror("fread"); return -1; } printf("r_buf:%s\n",r_buf); printf("r = %d\n",r); fclose(fp); return 0; }

    运行结果:

    格式化读写:

    fscanf(格式化输入) int fscanf ( FILE * fp, const char * format, … ); fscanf从fp中格式化输入 示例 fscanf(fd,"%s",buf);将fd所指向的文件里边的内容输入到buf中 fscanf(fp,"%d %s",&c,d);从fp所指向的文件里边读取一个整数给c,在读取一个字符串给d fprintf(格式化输出) int fprintf(FILE *fp, const char *format, …) fprintf格式化得到的字符串写到fp指向的文件里面 示例 fprintf(fd,"%s","what are you doing "); sprintf(格式化字符串复制) int sprintf(char str, const charformat, …) 把某一种类型的数据转换成字符串存放到某一个地址内 #include<stdio.h> main() { char * a=”This is string A!”; char buf[80]; sprintf(buf,” %s\n”,a); printf(“%s”.buf); }

    代码演示:

    #include <stdio.h> #include <string.h> int main() { int a = 10, b = 20; int c,d; char buff[12]; char buf[12]="helloworld";//空格会有影响 FILE *fp = NULL; fp = fopen("hello.txt","w+"); if(fp == NULL) { perror("fopen"); return -1; } fprintf(fp,"%d %d %s",a,b,buf);//以某种个数将内容写入指定文件 rewind(fp);//移动光标 fscanf(fp,"%d %d %s",&c,&d,buff);//读取 printf("c = %d d = %d buff = %s\n",c,d,buff);//打印读取内容 fclose(fp); return 0; }

    运行结果:

    文件指针定位: API

    rewind: void rewind(FILE *fp); 将读写指针定位到文件开始位置,无返回值 fseek:将读写指针定位到指定位置 fp:要操作的文件 offset:偏移量(可正可负) whence:参考位置 SEEK_SET //文件开始 SEEK_CUR //文件当前位置 SEEK_END //文件尾 ftell long ftell(FILE *fp); 返回当前文件读写指针的位置,常用来求文件的大小 作用 操作定位内部的读写指针

    代码演示:

    #include <stdio.h> #include <string.h> int main(int argc,char *argv[]) { FILE *fp=NULL; int w=0,r=0; char w_buf[12] = "hello world"; char r_buf[12]; memset(r_buf,0,sizeof(r_buf)); fp = fopen("hello.txt","w+"); if(fp == NULL) { perror("fopen"); return -1; } printf("打开文件成功\n"); w = fwrite(w_buf,1,sizeof(w_buf),fp); if(w < 12) { perror("fwrite"); return -1; } printf("w = %d\n",w); //fseek(fp,0,SEEK_SET); fseek(fp,-12,SEEK_CUR);//移动光标 r = fread(r_buf,1,sizeof(r_buf),fp); if(r < 12) { perror("fread"); return -1; } printf("r_buf:%s\n",r_buf); printf("r = %d\n",r); fclose(fp); return 0; }

    运行结果:

    2.文件I/O(缓冲区文件操作) 接口 (posix接口文件操作) 系统调用接口 中间没有经过缓冲区 实时性高 非常安全和快

    打开关闭:

    open 原型 int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); 头文件: (man 2 open) #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> 参数 pathname : 要打开文件的路径(相对路径、绝对路径) flag:(动作标志) O_RDONLY 读 O_WRONLY 写 O_RDWR 读写 O_CREAT 没有就创建 有就访问 O_EXCL 和O_CREAT连用如果有返回错误 O_TRUNC 将文件截取为0(如果有内容就清空里边的内容) O_APPEND 追加的方式打开 mode(权限) 当第二个参数有O_CREAT,表示创建文件的时候给定文件的权限 返回值 成功: 返回:文件描述符 失败: -1 close 原型:void close(int fd); 功能:关闭一个打开的文件 头文件 #include <unistd.h>

    演示代码:

    #include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> int main(int argc,char *argv[]) { int fd; if(argc < 2) { printf("请输入正确的参数\n"); return -1; } fd = open(argv[1],O_RDWR|O_CREAT,0666); if(fd < 0) { perror("open"); return -1; } printf("打开文件成功\n"); close(fd); return 0; }

    运行结果:

    读写操作:

    read 原型 ssize_t read(int fd, void *buf, size_t count); 头文件 #include <unistd.h> 功能 读文件内容到buf 参数 fd 要读文件的路径(相对路径、绝对路径) buf 要读入的缓冲区, 提前申请好的 count 要读入的字节数 返回值 成功: 返回:实际读的字节数 失败: -1 wirte 原型 ssize_t write(int fd, const void *buf, size_t count); 功能:将buf内容写入文件。 头文件: #include <unistd.h> 参数 fd:打开成功的文件描述符 buf:要写入的数据 提前申请好的 count:写入的数量 返回值 成功: 返回:实际读写的字节数 失败: -1

    演示代码:

    #include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <strings.h> #include <sys/types.h> int main(int argc,char *argv[]) { int fd; int r=0,w=0; char w_buf[12]="hello world"; char r_buf[12]; if(argc < 2) { printf("请输入正确的参数\n"); return -1; } fd = open(argv[1],O_RDWR|O_CREAT,0666); if(fd < 0) { perror("open"); return -1; } printf("打开文件成功\n"); bzero(r_buf,sizeof(r_buf)); w = write(fd,w_buf,12); if(w != 12) { printf("write error\n"); return -1; } printf("写成功\n w = %d\n",w); close(fd); fd = open(argv[1],O_RDWR|O_CREAT,0666); f(fd < 0) { perror("open"); return -1; } printf("打开文件成功\n"); r = read(fd,r_buf,12); if(r != 12) { printf("read error\n"); return -1; } printf("read成功\n r = %d\n",r); printf("r_buf:%s\n",r_buf); close(fd); return 0; }

    运行结果:

    指针定位(lseek):

    原型 off_t lseek(int fd, off_t offset, int whence); 功能 调整或得到文件当前读写的位置 头文件 头文件: #include <unistd.h> #include <sys/types.h> 参数 fp 用open打开的文件描述符 offset:想要调整的文件读写位置的相对偏移 负数向左移动 正数向右移动 whence: 调整文件读写位置的基准。 SEEK_SET:当前位置为文件的开头 SEEK_CUR:当前位置为文件指针的位置 SEEK_END:当前位置为文件的结尾

    演示代码:

    #include <stdio.h> #include <string.h> #include <fcntl.h> #include <unistd.h> #include <strings.h> #include <sys/types.h> int main(int argc,char *argv[]) { int fd; int r=0,w=0; char w_buf[12]="hello world"; char r_buf[12]; if(argc < 2) { printf("请输入正确的参数\n"); return -1; } fd = open(argv[1],O_RDWR|O_CREAT,0666); if(fd < 0) { perror("open"); return -1; } printf("打开文件成功\n"); bzero(r_buf,sizeof(r_buf)); w = write(fd,w_buf,12); if(w != 12) { printf("write error\n"); return -1; } printf("写成功\n w = %d\n",w); lseek(fd,0,SEEK_SET); //lseek(fd,-12,SEEK_CUR); //lseek(fd,-12,SEEK_END); r = read(fd,r_buf,12); if(r != 12) { printf("read error\n"); return -1; } printf("read成功\n r = %d\n",r); printf("r_buf:%s\n",r_buf); close(fd); return 0; }

    运行结果:

    参考结构流程图: 文件操作 注:需要使用xmind软件进行查看

    Processed: 0.010, SQL: 8