前言
文件描述符:
内核(kernel)利用文件描述符来访问文件。文件描述符是非负整数。打开现存文件或新建文件时,操作系统在内存构建一些数据结构来表示这个动态文件,然后内核会向进程返回一个文件描述符。读写文件需要使用文件描述符来指定待读写的文件。
文件描述符的作用域是当前进程,出了这个进程,文件描述符就没有意义。
以下是本篇文章正文内容,下面案例可供参考
一、打开文件:open()
SYNOPSIS
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
上述是open()的包含的头文件和函数原型。
功能:打开一个文件。打开成功返回一个文件描述符,否则返回-1.
参数:
pathname:要打开的文件名。
flag:访问的模式。
必选:O_RDONLY 只读、O_WRONLY 只写、O_RDWR 可读可写。
可选:O_CREAT:若文件不存在则创建文件,用这个则说明第三个参数mode,说明文件按权限。
O_EXCL:如果文件存在,则出错,文件描述符返回-1。
O_APPEND:每次写入都加到文件末端。
O_TRUNC:打开文件并清空文件内容。
mode:规定文件权限,0600,可读1,可写2,可执行4。
参考代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
fd = open("./file1.txt",O_RDWR);
if(fd == -1){ //打开失败
printf("Open file failed!\n");
fd = open("./file1.txt",O_RDWR|O_CREAT,0600);
if(fd > 0){//打开成功
printf("Open fail success! \nfd = %d\n",fd);
}
}
close(fd);
return 0;
}
二、往文件写内容:write()
SYNOPSIS
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
描述:往fd文件描述符所指向的文件写入count字节的buf内容。
参考代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int fd;
char *buf = "My new CSND biog!";
fd = open("./file1.txt",O_RDWR|O_CREAT|O_APPEND,0600);
//ssize_t write(int fd, const void *buf, size_t count);
printf("fd = %d\n",fd);
write(fd,buf,strlen(buf)); //往fd文件插入buf的内容。
close(fd);
return 0;
}
三、改变文件偏移量:lseek()
文件偏移量是指执行下一个read()或write()操作的文件起始位置,会以相对于文件头部起始点的文件当前位置表示。
SYNOPSIS
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
描述:用来控制该文件的读写位置。文件描述符fd,相对于whence,将文件偏移量调整offset个字节。当调用成功时则返回目前的读写位置,也就是距离文件开头多少个字节。若有错误则返回-1.
参数 whence 为下列其中一种:
SEEK_SET 参数offset 即为新的读写位置.
SEEK_CUR 以目前的读写位置往后增加offset 个位移量.
SEEK_END 将读写位置指向文件尾后再增加offset 个位移量. 当whence 值为SEEK_CUR 或
SEEK_END 时, 参数offet 允许负值的出现.
- 典型使用实例:
- 欲将读写位置移到文件开头时:
lseek(int fildes,0,SEEK_SET); - 欲将读写位置移到文件尾时:
lseek(int fildes,0,SEEK_END); - 想要取得目前文件位置时:
lseek(int fildes,0,SEEK_CUR);
实例演示:
/*
文件描述符fd指向的文件内容为,"ABCDEFG",读写指针指在G后面
*/
char *buf = "ABCDEFG";
int lsee = lseek(fd,-(strlen(buf)),SEEK_CUR);
/*将文件偏移量指在A的前面,即文件头。
参数lsee = 0
*/
部分参考:https://blog.csdn.net/jaken99/article/details/77686427
四、读取文件内容:read()
SYNOPSIS
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
描述:把文件描述符fd指向的文件读取count个字节内容,读取到buf中。
参考代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int fd;
int data = 100;
int data2;
fd = open("./file1.txt",O_RDWR|O_CREAT,0600);
int n_write = write(fd,&data,sizeof(int)); //往file1写100(此时指向0后面)
lseek(fd,0,SEEK_SET); //文件里的内容重新指向头
int n_read = read(fd,&data2,sizeof(int)); //读取file1里面的内容到data2
printf("read = %d\n",data2); //打印data2 ,输出100.
close(fd);
return 0;
}
五、小项目实践
1、实现cp指令
编程思路:
①打开Src文件;
②把Src文件内容读入缓冲区buf中;
③新建Des文件;
④把buf的内容写入Des文件中;
⑤关闭Des、Src文件。
参考代码如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
/************指令内容:./mycp Src.c Des.c************/
int main(int argc,char** argv)
{
int fdSrc;
int fdDes;
char *readBuf = NULL;
if(argc != 3){ //判断参数个数
printf("params error\n");
exit(-1);//不是3个则退出程序
}
fdSrc = open(argv[1],O_RDWR); //打开源文件
int size = lseek(fdSrc,0,SEEK_END); //返回文件内容的字节数
lseek(fdSrc,0,SEEK_SET); //文件内容指回文件头
readBuf = (char *)malloc(sizeof(char)*size + 8); //根据需要开辟缓冲区大小
read(fdSrc,readBuf,size); //读取文件内容到缓冲区
fdDes = open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600); //打开或创造目标文件
write(fdDes,readBuf,strlen(readBuf));//往目标文件写入源文件的内容
close(fdSrc);
close(fdDes);
return 0;
}