Linux文件编程


前言

文件描述符:
内核(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 允许负值的出现.
  • 典型使用实例:
  1. 欲将读写位置移到文件开头时:
    lseek(int fildes,0,SEEK_SET);
  2. 欲将读写位置移到文件尾时:
    lseek(int fildes,0,SEEK_END);
  3. 想要取得目前文件位置时:
    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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值