Linux文件编程

在windows中手动修改文件操作步骤:打开\创建文档,编辑文档,保存文档,关闭文档。在Linux中就是用代码操作文件使计算机自动化完成以上步骤。

Linux为此提供了一系列API,打开\创建文件:open,读写:write\read,光标定位:lseek,关闭:close

文件的打开

  1. 需要包含的头文件:使用man查询open,可以看到要使用open必须包含3个头文件,分别是:<sys/types.h>,<sys/stat.h>,<fcntl.h>

  1. 返回值:open函数有整数返回值,返回文件的文件描述符,用来区分不同的文件,相当于文件的索引。当文件打开成功时,返回的是非负整数,打开失败时返回负数

  1. 参数含义:

pathname:要打开的文件名(含路径,缺省位当前路径)

flags:打开方式,有三种方式,分别是O_RDONLY只读打开, O_WRONLY只写打开, O_RDWR 可读可写打开。

当附带了权限后,打开的文件就只能按照这种权限来操作,比如,我使用O_RDONLY打开文件之后,我不能对文件进行写操作,我只能读

以上3个参数中应当只指定一个,下列的参数是可以选择的:

  1. O-CREAT 若文件不存在则创建它。使用此选项是,需要同时说明第三个参数mode,用其说明该新文件的存取许可权限

  1. O_EXCL 如果同时制定了OCREAT,而文件已经存在,则返回-1

  1. O_APPEND 每次写时都加到文件的尾端

  1. O_TRUNC 若文件种本来有内容,而且位只读或只写成功打开,则将其长度截短为0

mode:一定是再flags中使用了O_CREAT标志,mode记录待创建的文件的访问权限。

  1. 作用:打开一个文件,并返回该文件的文件描述符,以便于对其进行读写等操作

  1. 相关应用

//打开当面目录下的file1文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main()
{
        int fd;
        fd=open("./file1",O_RDWR);
        printf("fd=%d\n",fd);
        return 0;
}

创建file1,使用可读可写的方式打开file1文件,编译运行,可以看到返回值为3

删除file1,再运行代码对其进行打开操作,返回值为-1

//打开当前目录下的file1文件
//当打开文件失败时,创建该文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main()
{
        int fd;

        fd=open("./file1",O_RDWR);

        if(fd==-1){
                printf("open file1 failed\n");
                fd=open("./file1",O_RDWR|O_CREAT,0600);//0600是文件的访问权限为文件所有者可读可写

                if(fd>0){
                        printf("create file1 successed\n");
                }
        }
        return 0;
}
 

文件的创建

  1. 需要包含的头文件:<sys/types.h>, <sys/stat.h>, <fcntl.h>

  1. 返回值:fd文件描述符

  1. 参数含义:

pathname:要创建的文件名(含路径,缺省位当前路径)

mode:创建模式

  1. S_IRUSR: 可读

  1. S_IWUSR: 可写

  1. S_IXUSR: 可执行

  1. S_IRWXU: 可读可写可执行

  1. 作用:从buf缓冲区中写入count个字节到文件中

  1. 相关应用:

//在当前目录下创建一个可读可写可执行得到file2文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

int main()
{
        int fd;
        char *buf="write file";
        fd =creat("./file2",S_IRWXU);

        return 0;
} 

文件写入操作

  1. 需要包含的头文件:<unistd.h>

  1. 返回值:写入成功,返回写入的字节个数,写入失败返回-1

  1. 参数含义:fd:文件描述符,buf:缓冲区 ,count:写入字节数

  1. 作用:从buf缓冲区中写入count个字节到文件中

  1. 相关应用:

//将“write file”写入file1文件中

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
int main()
{
        int fd;
        char *buf="write file";

        fd=open("./file1",O_RDWR);
        if(fd==-1){
                printf("open file1 failed\n");
                fd=open("./file1",O_RDWR|O_CREAT,0600);
                if(fd>0){
                        printf("create file1 successed\n");
               }
        }
        printf("open success  fd=%d\n",fd);
        write(fd,buf,strlen(buf));//此处不能使用sizeof,必须使用strlen,sizeof计算的是buf指针的大小,strlen计算的才是指针指向内容的字节大小
        close(fd);
        return 0;
}

文件读取操作

  1. 需要包含的头文件:<unistd.h>

  1. 返回值:读取成功,读到多少字节就返回多少;读取失败返回0;读取错误返回-1

  1. 参数含义:fd:文件描述符,buf:缓冲区 ,count:读取字节数

  1. 作用:从文件中读取count个字节到buf缓冲区

  1. 相关应用:

//读取file1文件中的内容

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
        int fd;
        char *buf="write file";

        fd=open("./file1",O_RDWR);
        if(fd==-1){
                printf("open file1 failed\n");
                fd=open("./file1",O_RDWR|O_CREAT,0600);
                if(fd>0){
                        printf("create file1 successed\n");
                }
        }
        printf("open success  fd=%d\n",fd);

        int cnt_write=write(fd,buf,strlen(buf));
        if(cnt_write !=-1){
                printf("write %d byte to file1\n",cnt_write);
        }

        close(fd);
        fd=open("./file1",O_RDWR);//此处关闭文件再重新打开的目的是让光标重新回到文件头,这样才能读取到写入的内容,也可以使用光标重定位lseek来进行此操作

        char *readBuf;
        readBuf=(char *)malloc(sizeof(char)*cnt_write+1);//这里必须对readBUf进行空间开辟,不然readBuf没有具体的指向,会发生段错误。

        int cnt_read=read(fd,readBuf,cnt_write);//读取的大小不一定必须是写入的大小,可以是任意值,但是读取到的内容,只有写入的内容那么大,比如读取的是100字节,但是读取完之后的内容依然只有10字节
        printf("read %d ,context:%s\n",cnt_read,readBuf);

        close(fd);
        return 0;
}

文件光标移动操作

在进行读取时,我们使用了关闭文件再重新打开文件的方式,这种方式就有点垃圾了,我们可以使用lessk直接移动光标

  1. 需要包含的头文件:<sys/types.h>,<unistd.h>

  1. 返回值:调用成功,返回对于文件头的偏移值

  1. 参数含义:

fd:文件描述符

offset:当offset为负数,对于whence往前移,当offset为正数,对于whence往后移

whence:

  1. SEEK_SET:文件头

  1. SEEK_CUR:当前位置

  1. SEEK_END:文件尾

  1. 作用:将文件读写指针相对whence移动offset个字节

  1. 相关应用:

//对于前面的读取文件内容的代码,进行修改

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
        int fd;
        char *buf="write file";

        fd=open("./file1",O_RDWR);
        if(fd==-1){

                printf("open file1 failed\n");
                fd=open("./file1",O_RDWR|O_CREAT,0600);
                if(fd>0){

                        printf("create file1 successed\n");
                }

        }
        printf("open success  fd=%d\n",fd);

        int cnt_write=write(fd,buf,strlen(buf));
        if(cnt_write !=-1){
                printf("write %d byte to file1\n",cnt_write);
        }
//      close(fd);      
//      fd=open("./file1",O_RDWR);   

        lseek(fd,-cnt_write,SEEK_END);//从文件尾像前移动写入的字节数,也相当于lssek(fd,0,SEEK_SET)

        char *readBuf;
        readBuf=(char *)malloc(sizeof(char)*cnt_write+1);

        int cnt_read=read(fd,readBuf,cnt_write);
        printf("read %d ,context:%s\n",cnt_read,readBuf);

        close(fd);
        return 0;
}
//巧用lseek对文件大小进行计算

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
        int fd;
        char *buf="write file";

        fd=open("./file1",O_RDWR);

        int fileSize=lseek(fd,0,SEEK_END);//利用lseek的返回值是对于文件头的偏移值,我们可以直接将光标移到文件尾,就可以巧妙的计算文件的字节大小了

        printf("file size is:%d\n",fileSize);

        close(fd);
        return 0;
} 

文件编程应用1——实现Linux cp命令

//main函数的参数,来读取cp aa bb命令中的两个文件

#include <stdio.h>

int main(int argc, char **argv) //argc是参数的总个数,argv是数组指针,每个数组指针指向的内容是相应的参数
{
        printf("total paeams:%d",argc);
        printf("No.1 params:%s\n",argv[0]);
        printf("No.2 params:%s\n",argv[1]);
        printf("No.3 params:%s\n",argv[2]);
        return 0;
}
//编写代码实现Linux cp命令
/*实现思路:打开源文件src.c,读源文件src.c到缓冲区buf,打开/创建目标文件des.c,将缓冲区buf的内容写入到目标des.c,关闭两个文件*/

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
        int fd_src;
        int fd_des;
        char *readBuf=NULL;
        if(argc !=3){
                printf("param error\n");
                exit(-1);
        }

        fd_src=open(argv[1],O_RDWR);
        int size=lseek(fd_src,0,SEEK_END);
        lseek(fd_src,0,SEEK_SET);
        readBuf=(char *)malloc(sizeof(char)*size+8);

        int n_read=read(fd_src,readBuf,size);
        fd_des=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);
        int n_write=write(fd_des,readBuf,strlen(readBuf));

        close(fd_src);
        close(fd_des);
        return 0;
}

文件编程应用2——修改程序的配置文件

在这之前需要先了解strstr()这个API

  1. 需要包含的头文件:<string.h>

  1. 返回值:需要找的特定字符串出现的首位置,返回的是一个字符型指针

  1. 参数含义:haystack:要操作的字符串 ,needle:找到的字符串

  1. 作用:从字符串中找出特定的字符串


现有配置文件如下,将LENG=3 修改为 LENG=5

//修改LENG=3为LENG=5的步骤如下
//1.找到LENG=3出现的首位置
//2.该位置记录下来
//3.再将位置向后移动到需要修改的地方,即移动到3的位置,再将5赋值给指针指向的位置

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
        int fd_src;
        char *readBuf=NULL;
        if(argc !=2){
                printf("param error\n");
                exit(-1);
        }

        fd_src=open(argv[1],O_RDWR);
        int size=lseek(fd_src,0,SEEK_END);
        lseek(fd_src,0,SEEK_SET);
        readBuf=(char *)malloc(sizeof(char)*size+8);

        int n_read=read(fd_src,readBuf,size);

        char *p=strstr(readBuf,"LENG=");

        if(p==NULL){
                printf("not found");
                exit(-1);
        }

        p=p+strlen("LENG+");
        *p='5';//一定要是字符'5',在文件中的内容都是字符型的

        lseek(fd_src,0,SEEK_SET);//光标重新定位,让缓冲区中修改后的内容重新覆盖掉源文件中的内容
        int n_write=write(fd_src,readBuf,strlen(readBuf));

        close(fd_src);
        return 0;
}

编译运行之后,再打开需要修改的文件,就可以看到已经修改好了

写一个整数到文件

上面修改文件配置文件时,写入文件的是一个字符,并且文件中的内容都是字符型的,那么怎样才能将一个整型数写入到文件呢

可以从手册中看到,buf其实是一个无类型的指针,所以不仅仅是可以传递一个字符型指针,也可以是一个指向整型数的地址

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
        int fd;
        int x=100;
        int y=0;
        fd=open("./file2",O_RDWR);
        int n_write=write(fd,&x,sizeof(int));//将x地址指向的值写入到file2里面
        lseek(fd,0,SEEK_SET);//光标重定位,将光标定位到文件头
        int n_read=read(fd,&y,sizeof(int));//从file2中将x读到y所指向的地址空间中
        printf("read:%d",y);        
        close(fd);
        return 0;
}

写结构体数组到文件

  1. 写结构体到文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct test
{
        int a;
        char b;
};

int main()
{
        int fd;
        struct test x={100,'a'};
        struct test y;
        fd=open("./file2",O_RDWR);
        int n_write=write(fd,&x,sizeof(struct test));
        lseek(fd,0,SEEK_SET);
        int n_read=read(fd,&y,sizeof(struct test));
        printf("read:%d,%c\n",y.a,y.b);
        close(fd);
        return 0;
}
  1. 写结构体数组到文件

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct test
{
        int a;
        char b;
};

int main()
{

        int fd;
        struct test x[2]={{100,'a'},{101,'b'}};
        struct test y[2];
        fd=open("./file2",O_RDWR);
        int n_write=write(fd,&x,sizeof(struct test)*2);
        lseek(fd,0,SEEK_SET);
        int n_read=read(fd,&y,sizeof(struct test)*2);
        printf("read:%d,%c\n",y[0].a,y[0].b);
        printf("read:%d,%c\n",y[1].a,y[1].b);
        close(fd);
        return 0;
}

以此类推,也可以将链表等写入到文件中

标准C库打开创建文件读写光标移动

#include <stdio.h>
#include <string.h>
int main()
{

        FILE *fp;
        char readBuf[1024]={0};
        char *str="write file";

        fp=fopen("./file1","w+");
        fwrite(str,sizeof(char),strlen(str),fp);
        fseek(fp,0,SEEK_SET);
        fread(readBuf,sizeof(char),strlen(str),fp);
        printf("read data: %s\n",readBuf);
        fclose(fp);
        return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值