系统调用函数
open 函数
利用man 2 open命令查看open函数所需包含的头文件以及函数原型,调用细节 函数原型如下: int open(const char pathname, int flags); / 比较常用*/ int open(const char *pathname, in tflags, mode_t mode); 函数参数 pathname:路径名
flags:以什么模式打开文件 常见的参数有: O_RDONLY:只读 O_WRONLY:只写 O_RDWR:可读可写 O_APPEND 表示追加,如果原来文件里面有内容,则这次写入会写在文件的最末尾。0x00002000 O_CREAT 表示如果指定文件不存在,则创建这个文件 0x0000 0100
mode:文件权限 -0755 -0666
返回值:open成功返回fd(文件描述符),失败返回-1
close 函数
函数原型: int close(int fd);
read 函数
函数原型: ssize_t read(int fd,void * buf, size_ t count); 含义:从fd所指的文件中读取t_count个字节到缓冲区buf中 函数参数: fd:open函数返回的文件描述符 buf:缓冲区 t_count:字节数 返回值:成功读取的字节数,失败返回-1,若在read之前光标已经到达文件末尾也返回0
write 函数
函数原型:ssize_t write (int fd,const void * buf, size_t count); 含义:从buf中取t_count字节的字符写到fd所指文件中 函数参数: fd:文件描述符 buf:缓冲区 t_count:字节数 返回值:实际写入的字节数,错误返回-1
lseek 函数
函数原型:off_t lseek(int fd, off_t offset, int whence); 含义:光标的偏移量 函数参数: fd:文件描述符 offset:从whence所设光标开始的偏移量 whence:从哪开始 常见参数: SEEK_SET: 参数offset即为新的读写位置 SEEK_CUR: 以目前的读写位置往后增加offset个偏移量 SEEK_END: 将读写位置指向文件尾后再增加offset个位移量,当whence值为SEEK_CUR或SEEK_END时, 参数offset允许负值的出现。 返回值:光标与文件开头的距离几个字节
利用文件操作实现cp指令
cp file1 file2
由于需要在终端调用函数实现cp指令 所需流程如下: 1.将src_file 赋值为file1(argv[1]),将des_file赋值为file2(argv[2]) 1.打开src_file ,des_file 2.利用read函数将src_file 文件数据存入readBuff 3.利用write函数将readBuff中的数据写入des_file 4.关闭src_file ,des_file 代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char *argv[]){
printf("paramTotal:%d\\n",argc);
if(argc<3){
printf("error\\n");
return –1;
}
char src_file[20] = {};
char des_file[20] = {};
strcpy(src_file,argv[1]);
strcpy(des_file,argv[2]);
printf("src_file = %s\\n",src_file);
printf("des_file = %s\\n",des_file);
int src_fd = open(src_file,O_RDWR|O_CREAT,0755);
if(src_fd==–1){
printf("open file %s failed\\n",src_file);
return 0;
}
int des_fd = open(des_file,O_RDWR|O_CREAT,0755);
if(des_fd==–1){
printf("open file %s failed\\n",des_file);
return 0;
}
char readBuff[128] = {};
while (1){
int nRet = read(src_fd,&readBuff[0],128);
printf("nRet = %d\\n",nRet);
if(nRet==0){
break;
}
write(des_fd,readBuff,nRet);
memset(readBuff,0,128);
}
close(src_fd);
close(des_fd);
}
标准c库函数
fopen 函数
函数原型:FILE * fopen(constchar *path , cost char *mode) 函数参数: path :文件描述符 mode:读写模式 mode有以下值: r:只读方式打开,文件必须存在 r+:可读写,文件必须存在 rb+:打开二进制文件,可以读写 rt+:打开文本文件,可读写 w:只写,文件存在则文件长度清0,文件不存在则建立该文件 w+:可读写,文件存在则文件长度清0,文件不存在则建立该文件 a:附加方式打开只写,不存在建立该文件,存在写入的数据加到文件尾,EOF符保留 a+:附加方式打开可读写,不存在建立该文件,存在写入的数据加到文件尾,EOF符不保留 wb:打开二进制文件,只写 wb+:打开或建立二进制文件,可读写 wt+:打开或建立文本文件,可读写 at+:打开文本文件,可读写,写的数据加在文本末尾 ab+:打开二进制文件,可读写,写的数据加在文件末尾
返回值:FILE指针,失败返回NULL
fclose 函数
函数原型 int fclose(FILE*stream) 返回值:成功返回0,失败返回EOF
fread 函数
函数原型: size_t fread(void* buff , size_t size, size_t count , FILE* stream) 含义:从stream所指的文件中读取size*count 个字节到缓冲区buff中 函数参数: buff :buff缓冲区 size:每个数据项包含几个字节 count :数据项个数 stream:需要读取的文件流 返回值:实际读取的数据项个数
fwrite 函数
函数原型:int fwrite(voidbuffer,int size,int count,FILEfp) 含义:从buff中取size*count 个字节写到fp所指文件中 函数参数: buff :buff缓冲区 size:每个数据项包含几个字节 count :数据项个数 fp:需要写入的文件流 返回值:实际写入的数据项个数
fseek 函数
函数原型: int fseek(FILE *stream,long offset,int framewhere) 含义:光标位置为文件流stream中从framewhere位置起偏移offset单位 函数参数: stream:文件流 offset:偏移量 framewhere:定位 framewhere所使用的三个宏 SEEK_SET 既0 文件开头 SEEK_CUR 既1 文件当前位置 SEEK_END 既2 文件结尾 返回值:重定位成功返回0,否则返回非0
利用标准c库函数实现cat命令
#include <stdio.h>
int main(int argc ,char *argv[]){
FILE *fp;
char readBuff[128] = {};
fp = fopen(argv[1],"r");
if(fp==NULL){
printf("open file failed\\n");
return –1;
}
printf("open file success\\n");
while(fgets(readBuff,128,fp)!=NULL){
fputs(readBuff,stdout);
}
// while(1){
// int nRead = fread(readBuff,1,sizeof(readBuff),fp);
// if(nRead == 0){
// break;
// }
// fwrite(readBuff,1,nRead,stdout);
// }
fclose(fp);
return 0;
}
三类缓存
全缓存
写满缓存后再执行系统调用函数 读:fread 写: fwrite
无缓存
执行函数就调用系统调用函数,将其内容 写入内核 stderr
行缓存
读取到换行符后执行系统调用函数 读:fgets,gets,fgetc,printf,fprintf,sprintf 写:fputs,puts,fputc
gets和fgets区别:gets无法指定缓存长度,可能造成缓存越界,如果新行长度大于缓冲区;gets只能从标准输入中读取;gets不将新行存入缓存,fgets将新行存入缓存
puts和fputs区别:puts输出添加新行,fputs输出不添加新行
刷新缓存函数
fflush(FIFE *fp) 用于将库函数缓存强行写入内核缓存
close与fcolse中包含了fflush函数,关闭文件后会自动将库函数缓存写入内核缓存





