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

文件操作(标准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软件进行查看

猜你喜欢

转载自blog.csdn.net/weixin_40734514/article/details/108959562