open函数的应用:
open函数的使用需要包含三个头文件
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
我们可以使用man手册可以查看该函数原型
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
*pathname为要打开的文件名例如“./file1”,flags含有三种模式O_RDONLY(只读打开),O_WRONLY(只写打开),O_RDWR(可读可写打开)。以上三个常数应当只指定一个,下列常数是 可选择的:
O_CREAT //若文件不存在则创建它,还需说明第三个参数,赋予文件权限
O_EXCL //如果指定了O_CREAT,而文件存在,则出错
O_APPEND //每次写时都加到文件尾端
O_TRUNC //覆盖原有内容
具体示例
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
int main(){
int fd; //fd为文件描述符
fd=open("./file1",O_RDWR); //打开这个文件,用可读可写的权限
if(fd==-1)
{
printf("fd\n");
fd=open("./feil1",O_RDWR|O_CREAT,0600); //如果文件不存在,就创建这个文件
if(fd>0){
printf("create file1\n");
}
}
return 0;
}
0600就可以看为4+2即可读,可写。
读写操作函数
写入操作
写入操作我们使用write函数我们使用man手册查看它的函数原型
#include <unistd.h>
我们在使用时需要使用这个头文件。它的函数原型为
ssize_t write(int fd, const void buf[.count], size_t count);
可以看出它的参数为文件描述符FD,缓冲区BUF(需要注意的是BUF为字符指针),字符串大小count。具体使用案例
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
int main(){
int fd;
char *buf="hello"; //要写入的数据BUf
fd=open("./file1",O_RDWR); //打开file1文件,使用可读可写的方式
if(fd==-1)
{
printf("fd create error\n"); //判读文件描述符FD大小,如果FD为负则文件打开失败
fd=open("./file1",O_RDWR|O_CREAT,0600); //在此创建文件,或者使用权限创建
if(fd>0){
printf("create file1\n"); //文件创建成功
}
printf("open success :fd=%d\n",fd);
int n_write=write(fd,buf,strlen(buf)); //在文件内写入BUF,用strlen计算字符串的大小
if(n_write !=-1){
printf("write %d byte to file \n",n_write ); //判断返回值大小,返回值为字符串大小
}
close (fd);
}
return 0;
}
读取操作
读取操作我们用man手册来查看函数原型以及所用的头文件
#include <unistd.h>
函数原型为
ssize_t read(int fd, void buf[.count], size_t count);
分析它的函数原型我们可以知道文件描述符FD,所要读取的字符串BUF,大小count
具体使用案例
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
int main(){
int fd;
char *buf="niuchenghui";
fd=open("./file1",O_RDWR);
if(fd==-1)
{
printf("fd\n");
fd=open("./feil1",O_RDWR|O_CREAT,0600);
if(fd>0){
printf("create file1\n");
}
printf("open success :fd=%d\n",fd);
int n_write=write(fd,buf,strlen(buf));
if(n_write !=-1){
printf("write %d byte to file \n",n_write );
}
char *readbuf;
readbuf=(char *)malloc(sizeof(char)*n_write+1); //我们动态创建一个内存大小
int n_read=read(fd,readbuf,n_write);
printf("read %d,context:%s\n",n_read,readbuf);
close (fd);
}
return 0;
}
这么做有一个问题是,我们在读取时光标在字符串的最后,所以显示的是 无任何数据,基于此我们有两种解决方案重新打开或者将光标移动到最开始,现在我们就先使用第一种方案
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
int main(){
int fd;
char *buf="hello";
fd=open("./file1",O_RDWR);
if(fd==-1)
{
printf("fd\n");
fd=open("./file1",O_RDWR|O_CREAT,0600);
if(fd>0){
printf("create file1\n");
}
printf("open success :fd=%d\n",fd);
int n_write=write(fd,buf,strlen(buf));
if(n_write !=-1){
printf("write %d byte to file \n",n_write );
}
close (fd); //在开始读之前我们先关闭之后重新打开,使得光标移动到光标头
fd=open("./file1",O_RDWR);
char *readbuf;
readbuf=(char *)malloc(sizeof(char)*n_write+1); //
int n_read=read(fd,readbuf,n_write);
printf("read %d,context:%s\n",n_read,readbuf);
close (fd);
}
return 0;
}
光标移动
在上部分我们说有两种方案,一种为移动光标,一种为重新打开,我们试了重新打开的方式,这次我们使用移动光标的方案。通过man函数查询他所需要的头文件是
#include <unistd.h>
函数原型为
off_t lseek(int fd, off_t offset, int whence);
这个函数的作用是将文件读写指针相对whence移动offset个字节
offset偏移值,whence相对位置。
whence有三种类型第一种SEEK_SET代表文件头
SEEK_END代表文件尾,SEEK_CUR代表光标位置。具体案例
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
int main(){
int fd;
char *buf="niuchenghui";
fd=open("./file1",O_RDWR);
if(fd==-1)
{
printf("fd\n");
fd=open("./file1",O_RDWR|O_CREAT,0600);
if(fd>0){
printf("create file1\n");
}
}
printf("open success :fd=%d\n",fd);
int n_write=write(fd,buf,strlen(buf));
if(n_write !=-1){
printf("write %d byte to file \n",n_write );
}
// close(fd);
// fd=open("./file1",O_RDWR);
char *readbuf;
readbuf=(char *)malloc(sizeof(char)*n_write+1);
lseek(fd,0,SEEK_SET); //在这段代码中我们就将光标移动到文件的头部相对零个位置
int n_read=read(fd,readbuf,n_write);
printf("read %d,context:%s\n",n_read,readbuf);
close (fd);
return 0;
}
基于此段代码我们可以写出其他两种方式的光标移动,需要注意的是lseek_CUR偏移为负。
cp命令实现
基于以上内容我们可以写一个小例子实现linux的cp命令实验思路
1.打开原文件src
2.读取src文件到buf里面
3.打开或者创建des目标文件
4.将buf里面内容写入des里面
5.关闭两个文件
具体示例代码
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
int main(int argc,char **argv){ //argc为参数cp 源文件 目标文件
//argv为目标数组与原数组的二级指针
int fdSrc;
int fdDes;
char *readBuf=NULL;
if(argc !=3){ //判断参数是否正常
printf("pararm error\n");
exit(-1);
}
//此处打开的argv[1]为源文件
fdSrc=open(argv[1],O_RDWR); //cp为argv[0],源文件为argv[1],目标文件为argv[2]
int size=lseek(fdSrc,0,SEEK_END);
lseek(fdSrc,0,SEEK_SET);
readBuf=(char *)malloc(sizeof(char)*size+8); //计算readbuf的大小,并动态创建
int n_read=read(fdSrc,readBuf,size);
fdDes=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600); //O_TRUNC使用它将其目标文件内的内容全部截取覆盖
int n_write=write(fdDes,readBuf,strlen(readBuf));
close(fdSrc);
close (fdDes);
return 0;
}
修改文件内容
如果我们需要修改文件内容的一部分。我们应该怎么操作。假设我们需要找到LENG=5这个字段,我们需要更改5这个数字那么我们先需要找到L然后计算往后偏移几个位置才能替换5,根据这个思路我们写代码
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
int main(int argc,char **argv){
int fdSrc;
char *readBuf=NULL;
if(argc !=2){
printf("pararm error\n");
exit(-1);
}
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);
int n_read=read(fdSrc,readBuf,size);
char *p=strstr(readBuf,"LENG="); //此函数的作用是将指针指向文件中L的位置
if(p==NULL){ //如果等与空则证明没有找到
printf("no found\n");
exit(-1);
}
p=p+strlen("LEMG="); //移动指针
*p='5'; //替换内容
lseek(fdSrc,0,SEEK_SET);
int n_write=write(fdSrc,readBuf,strlen(readBuf));
close(fdSrc);
return 0;
}
strstr函数的作用:
1、strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。
2、找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址;
3、如果未找到所搜索的字符串,则返回NULL。
写一个整数和结构体到文件
我们在上述的所有操作中都是写一个字符或者字符串,但其实都是它的指针,我们要
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
int main(){
int fd;
int data=100;
int data2=0;
fd=open("./file1",O_RDWR);
int n_write=write(fd,&data,sizeof(int)); //对于data取地址,计算它的大小
lseek(fd,0,SEEK_SET);
int n_read=read(fd,&data2,sizeof(int));
printf("read %d \n",data2);
close (fd);
return 0;
}
想在文件中写一个整数进去我们其实只需要将这个整数进行取地址就好。
根据以上内容我们可以知道将结构体写入文件
#include <fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
#include <unistd.h>
#include<string.h>
#include<stdlib.h>
struct Test
{
int a;
char c;
};
int main(){
int fd;
struct Test data={100,'a'};
struct Test data2;
fd=open("./file1",O_RDWR);
int n_write=write(fd,&data,sizeof(struct Test)); // 计算整个结构体的大小
lseek(fd,0,SEEK_SET);
int n_read=read(fd,&data2,sizeof(struct Test));
printf("read %d,%c \n",data2.a,data2.c);
close (fd);
return 0;
}