C语言的io操作
写文件
#include<stdio.h>
#include<string.h>#define FILE_NAME "log.txt"
int main()
{FILE * fp = fopen(FILE_NAME, "w");if(fp==NULL){printf("fopen error!\n");}const char* msg = "hello zk\n";int cnt =5;while(cnt--){fwrite(msg,strlen(msg),1,fp);}fclose(fp);return 0;
}
接口介绍
fopen函数,第一个参数是文件的路径,第二个参数是mode 有 r w r+ w+等等.返回值返回的是一个文件指针。
r:只读,不存在文件则会报错。
w:写文件,不存在文件则会创建一个文件
r+:读写文件,不存在文件则会报错
w+::读写文件,不存在文件则会创建一个文件
FILE *fopen(const char *path, const char *mode);
fclose,参数是是一个文件指针
int fclose(FILE *fp);
fwrite
参数的意义,第一个是写的消息,第二个是消息的大小,第三个是每一个字符的大小,最后一个是文件指针。
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
结果
读文件
#include<stdio.h>
#include<string.h>#define FILE_NAME "log.txt"
int main()
{FILE * fp = fopen(FILE_NAME, "r");if(fp==NULL){printf("fopen error!\n");}char buffer[1024];//while(cnt--)//{//fwrite(msg,strlen(msg),1,fp);//}while(fgets(buffer, sizeof(buffer), fp) != NULL) // 使用sizeof并检查返回值{printf("%s", buffer); // fgets自动添加'\0'和保留换行符,不需额外处理}fclose(fp);return 0;
}
结果
[zk@VM-24-17-centos lesson16]$ ./test
hello zk
hello zk
hello zk
hello zk
hello zk
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);char *fgets(char *s, int size, FILE *stream);
追加文件
#include<stdio.h>
#include<string.h>#define FILE_NAME "log.txt"
int main()
{FILE * fp = fopen(FILE_NAME, "a");if(fp==NULL){printf("fopen error!\n");}//char buffer[1024];const char* msg = "hello zk\n";int cnt=5;while(cnt--){fwrite(msg,strlen(msg),1,fp);}//while(fgets(buffer, sizeof(buffer), fp) != NULL) // 使用sizeof并检查返回值//{//printf("%s", buffer); // fgets自动添加'\0'和保留换行符,不需额外处理//}fclose(fp);return 0;
}
结果
接下来就是操作系统的接口了
open
int open(const char *pathname, int flags);int open(const char *pathname, int flags, mode_t mode);
c语言,java语言,python语言。都有io操作,那操作系统只有一个,怎么版本。那就学习操作系统的接口。知其所以然
我们先介绍flag是什么。在C语言中没有bool类型,这时候用bit位来当作标志的判断。
O_CREAT 创建
O_APPEND 追加
O_TRUNC 清空
O_RDONLY 只读
O_WRONLY 只写
我们先介绍这个东西的原理
看代码
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define ONE (1<<0) // 0000 0001
#define TWO (1<<1) // 0000 0010
#define THREE (1<<2) // 0000 0100
#define FOUR (1<<3) // 0000 1000void print1(char n)
{if(n&ONE){printf("one");}if(n&TWO){printf("two");}if(n&THREE){printf("three");}if(n&FOUR){printf("four");}printf("\n");
}
int main()
{print1(ONE);print1(ONE|TWO);return 0;
}
[zk@VM-24-17-centos lesson16]$ ./test
one
onetwo
前面的4个宏就相当于这里的define,
现在来看看使用
int open(const char *pathname, int flags);ssize_t write(int fd, const void *buf, size_t count);
看代码
第三个参数为创建文件的权限。有一个接口没有第三个参数,那是让文件已经存在的进行的操作。
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<string.h>#define FILE_NAME "log1.txt"int main()
{int fd = open(FILE_NAME,O_WRONLY|O_CREAT|O_TRUNC,0666);if(fd==-1){printf("open error");return -1;}printf("%d\n",fd);const char*msg="hello zzkk\n";int cnt =5;while(cnt--){ssize_t num = write(fd,msg,strlen(msg));}close(fd);return 0;
}
这里我打印了fd,为什么是3.先记住,后面讲
输出结果。
读文件
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<string.h>#define FILE_NAME "log1.txt"int main()
{int fd = open(FILE_NAME,O_RDONLY);if(fd==-1){printf("open error");return -1;}printf("%d\n",fd);const char*msg="hello zzkk\n";int cnt =5;char buffer[1024];while(1){int n = read(fd, buffer, sizeof(buffer)-1);buffer[n]=0;printf("%s\n",buffer);if(n==0){break;}}// while(cnt--)// {// ssize_t num = write(fd,msg,strlen(msg));// }close(fd);return 0;
}
结果
[zk@VM-24-17-centos lesson16]$ ./test
3
hello zzkk
hello zzkk
hello zzkk
hello zzkk
hello zzkk
这里也有一个3.
这里为什么是3,而不是其他的。还有 0 1 2 去哪里了
C默认会打开三个输入输出流,分别是stdin, stdout, stderr ,这三个分别就是0 1 2
仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include<string.h>#define FILE_NAME "log1.txt"int main()
{printf("%d\n",stdin->_fileno);printf("%d\n",stdout->_fileno);printf("%d\n",stderr->_fileno);int fd = open(FILE_NAME,O_RDONLY);printf("%d\n",fd);close(fd);return 0;
}
[zk@VM-24-17-centos lesson16]$ ./test
0
1
2
3
open函数返回值
上面的 fopen fclose fread fwrite 都是C标准库当中的函数,我们称之为库函数(libc)。而, open close read write lseek 都属于系统提供的接口,称之为系统调用接口。