4月「掘金·日新计划」第3天
一、fopen与open
1.1、来源
- open是UNIX系统调用的函数
- fopen是标准C语言库函数
1.2、移植性
- fopen有良好移植性
- open只有在Linux下用
1.3、适用范围
- open,Linux下一切皆文件,硬件设备,网络套接字等
- fopen,普通正规文件
1.4、文件IO层次
- 低级IO,高级IO
- 谁离内核近
1.5、缓存
- 缓存文件系统,缓冲区,速度快,效率高,fopen
- 非缓存文件系统,通过内核访问,open
二、C库函数
2.1、fopen
参数:
- 文件名
- 什么权限,w+
返回值:
- FILE *fp
2.2、fwrite
参数:
- 缓冲区
- 一次写多少个字节
- 写多少次
- FILE *fp
返回值:
- 第三个参数
2.3、fread
参数:
- 缓冲区
- 一次写多少个字节
- 写多少次
- FILE *fp
返回值:
- 第三个参数
2.4、fseek
参数:
-
fp
-
偏移值,0不偏移,正往后,负往前 针对whence偏移
-
光标移动到位置
- SEEK_SET,头
- SEEK_GND,尾
- SEEK_CUR,当前位置
2.5、fclose
参数:fp
2.6、fputc
写一个字符到文件,写多个字符可以配合for实现
参数:
- 一个字符
- fp
2.7、fget
从文件获取一个字符
参数:fp
返回值:获取到的字符char
2.8、feof
判断是否到达文件的尾
参数:fp
返回值:
- 到达尾,返回非0
- 未到达,返回0
2.10 ftell
ftell(FILE*fp)函数返回光标位置(相当于头和lseek返回值一样),c库函数
三、应用实践
3.1、cp命令实现
3.1.1、main函数参数
int main (int argc, char **argv)
{
return 0;
}
- argc,参数总个数
- argv,char形二维数组,argv[0]...
3.7.2、cp实现
/***********************************************************************************
cp命令实现
***********************************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main(int argc, char **argv)
{
int fd; //cp到的文件描述符
int cpfd; //cp的文件描述符
int rsize = 0, wsize = 0; //读写的个数
int size = 0; //文件大小
char *buf = NULL; //读缓冲区
char input[10] = {'\0'}; //用户输入缓存
if(argc < 3){ //判断main参数个数是否正确
printf("Parameter error\n"); //参数错误
goto Parameter; //错误处理
}
printf("The number of parameters is correct...\n"); //参数数量正确
cpfd = open(argv[1], O_RDONLY); //打开cp的文件
if(cpfd < 0){
perror("target File open failed"); //打开失败,输出失败原因
goto Parameter;
}
printf("%s open success...\n", argv[1]); //文件打开成功
size = lseek(cpfd, 0, SEEK_END); //计算文件大小
if(size < 0){
perror("lseek error"); //失败并输出失败原因
goto LseekError;
}
printf("document size %d...\n", size); //文件大小
buf = (char *)malloc(sizeof(char)*size); //分配内存空间
if(buf == NULL){
printf("malloc error\n"); //失败并输出失败原因
goto LseekError;
}
printf("malloc success...\n"); //内存分配成功
if(lseek(cpfd, 0, SEEK_SET) < 0){ //光标指向头
perror("lseek error"); //失败并输出失败原因
goto LseekError;
}
printf("Cursor movement success...\n"); //光标移动成功
rsize = read(cpfd, buf, size); //读文件
if(rsize < 0){
perror("read error"); //失败并输出失败原因
goto MallocError;
}
printf("read %d byte success...\n",rsize); //读取个数成功
fd = open(argv[2], O_WRONLY|O_CREAT|O_EXCL, 0600); //打开或创建文件
if(fd < 0){ //有错误
if(errno == 17){
printf("File exists\n"); //错误是因为文件存在
printf("Do you want to continue opening,yes/no?\n"); //是否继续打开
scanf("%s",input); //输入yes打开文件并清除内容
if(!strcmp("yes", input)){
printf("Reopening file...\n"); //正在重新打开
fd = open(argv[2], O_WRONLY|O_TRUNC);
}else{
perror("target File open failed");
goto MallocError;
}
}
}
if(fd < 0){ //有错误
perror("target File open failed");
goto MallocError;
}
printf("%s open success...\n", argv[2]); //文件打开成功
wsize = write(fd, buf, size); //写文件
if(wsize < 0){
perror("write error"); //失败并输出失败原因
goto WriteError;
}
printf("wead %d byte success...\n",wsize); //写入个数成功
close(fd);
free(buf);
close(cpfd);
printf("close %s success...\n",argv[2]);
printf("malloc Memory release success...\n");
printf("close %s success...\n",argv[1]);
return 0;
WriteError:
close(fd);
printf("close %s success...\n",argv[2]);
MallocError:
free(buf);
printf("malloc Memory release success...\n");
LseekError:
close(cpfd);
printf("close %s success...\n",argv[1]);
Parameter:
return -1;
}
- 判断参数是否正确
- 打开文件,lseek计算文件大小,malloc分配buf,read
- 创建或打开目标文件,wirte
- 关闭2文件,free内存空间