C文件I/O相关操作:
fopen: FILE *fopen(const char *path, const char *mode);
1 #include<stdio.h>
2 #include<errno.h>
3 #include<string.h>
4
5 int main()
6 {
7 FILE *fp;
8 fp=fopen("./tmp.txt","r+"); // r+以读写方式打开文件(文件必须存在)
9 if(fp==NULL) //如果没有tmp.txt,会返回空
10 {
11 perror("fopen error");
12 return -1;
13 }
14 const char *msg="happy day!\n";
15 int count=5;
16 int ret=0;
17 while(count--)
18 {
19 // size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
20 // fwrite:第一次打开文件会覆盖式写入,当以后写入时会在文件末尾写入
21 ret=fwrite(msg,strlen(msg),1,fp);
22 if(ret==0) //fwrite出错返回0
23 perror("fwirte error");
24 }
25 fclose(fp);
26 return 0;
27 }
a+与fread、fwrite
fread和fwirte用于读写记录,这里的记录是指一串固定长度的字节,比如一个int ,一个结构体等。
size:一条记录的大小,nmemb是要读写多少条记录,这些记录在ptr所指的内存空间连续存放,共占sizenmemb个字节,fread从文件stream中读sizenmemb个字节保存到ptr中,而fwrite把ptr中size*nmemb个字节写到文件stream中。
nmemb是请求读或写的记录数,fread和fwrite返回的实际记录数小于等于nmemb,例如当前读写位置距文件末尾只有一条记录的长度,而nmemb为2,但是会返回1.如果当前读写位置已经在文件末尾或者读文件出错,fread会返回0;如果写文件出错,则fwrite的返回值小于nmemb值。
1 #include<stdio.h>
2 #include<string.h>
3
4 int main()
5 {
6 FILE *fp=fopen("./test.txt","a+");//读写打开文件,文件读写位置刚打开时在起始位置,写入后文件读写位置移动到文件末尾
7 if(fp==NULL)
8 {
9 perror("fopen error");
10 return -1;
11 }
12 const char ptr[]="hhahhahhaahh";
13 char msg[1024]={0};
14
15 // size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
16 fread(msg,sizeof(char),1024,fp); //第一次打开文件,会从文件起始位置开始读
17 printf("%s",msg);//如果是用户在文件写入默认有\n
18 printf("写入后:*************************\n");
19
20 //size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
21 fwrite(ptr,sizeof(char),strlen(ptr),fp);
22
23 //写入后读写位置移动到文件末尾,所以现在读取不到任何内容
24 char str[1024]={0};
25 int ret= fread(str,sizeof(char),1024,fp);
26 printf("ret:%d\n",ret);//0
27 printf("%s",str);//没有内容
28 fclose(fp);
29 return 0;
30 }
fseek:
fseek 移动跳转当前读写位置。
whence:
SEEK_SET:从文件起始位置开始偏移;
SEEK_CUR:从文件当前位置开始偏移;
SEEK_END: 从文件末尾位置开始偏移。
offset :
指相对偏移位置偏移量。
几种输出到显示器函数:
1 #include<stdio.h>
2 #include<string.h>
3
4 int main()
5 {
6 printf("hello,printf\n");
7
8 // stdout标准输出 显示器在linux下是文件,在linux下一切皆文件
9 // size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
10 const char *ptr="hello,fwrite!\n";
11 fwrite(ptr,sizeof(char),strlen(ptr),stdout);
12
13 //int fprintf(FILE *stream, const char *format, ...);
14 // fprintf格式化写入
15 fprintf(stdout,"fprintf:%s-%d\n","hello",2018);
16
17 return 0;
18 }
系统调用
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<fcntl.h>
4 #include<sys/types.h>
5 #include<sys/stat.h>
6 #include<string.h>
7 int main()
8 {
9 int fd=-1;
10 fd=open("./mytest.c",O_RDWR|O_CREAT,0664);
11 if(fd<0)
12 {
13 perror("open error");
14 return -1;
15 }
16 //write(int fd,void *buf,size_t count);
17 //在buf中读取count字节写入到fd文件中
18 const char *buff="no pains,no gains\n";
19 int ret1=write(fd,buff,strlen(buff));
20 printf("ret1:%d\n",ret1);
21
22 lseek(fd,0,SEEK_SET);//跳转fd所代表文件读写位置至起始位置的0偏移量处,即从文件开始读
23 //lseek(fd,-5,SEEK_END);
24 //lseek(fd,-5,SEEK_CUR);
25
26 char tmp[1024]={0};
27 //read(int fd,void *buff,size_t count);
28 //在文件fd中读取count字节到buf中
29 int ret=read(fd,tmp,strlen(buff)-2);
30 printf("ret:%d\n",ret);
31 printf("tmp:%s\n",tmp);
32 //read后读写位置发生变化
33 char msg[1024]={0};
34 lseek(fd,0,SEEK_SET);
35 read(fd,msg,13);
36 printf("msg:%s\n",msg);
37 return 0;
38 }
库函数和系统调用的关系
库函数:文件流指针-------C库IO接口的句柄
系统调用: 文件描述符:-----系统调用io接口的句柄
库函数是对系统调用的一层封装,上下级调用关系;
文件流指针结构体包含了一个成员即文件描述符,文件流指针中还定义一个缓冲区,所说的换行刷新缓冲区,即刷新这个缓冲区,这个缓冲区用于将短小数据组合成大数据一次性写入文件,这样可以提高效率,而刷新缓冲区就是缓冲区有内容就会写入文件;
但是系统调用没有这个缓冲区。
1#include<stdio.h>
2 #include<string.h>
3
4 int main()
5 {
6 printf("hello,printf");
7
8 const char *ptr="hello,fwrite!";
9 fwrite(ptr,sizeof(char),strlen(ptr),stdout);
10
11 fprintf(stdout,"fprintf:%s-%d","hello",2018);
12
13 const char* msg="hello,write";
14 write(1,msg,strlen(msg));
15
16 sleep(5);
17 printf("\n");
18 return 0;
19 }
write输出没有缓冲区影响,直接打印在终端,而printf,fprintf,fwrite有缓冲区影响,在5秒后打印在终端。