Linux应用开发-文件IO操作

Linux应用开发-文件IO操作

文件描述符

Linux中一切设备都可以当做是文件!!

通过调用系统中的I/O函数对文件进行相应的操作(open()close()write()、**read()**等)

当打开已经存在的文件或新创建的文件时,系统会返回一个文件描述符,他是用来指定已打开的文件。此文件描述符相当于打开这个文件的标号,是非负整数,操作这个文件描述符相当于操作这个相应的文件。

程序运行起来后(每个进程)都有一张文件描述符的表,标准输入、标准输出、标准错误输出设备文件被打开,对应的文件描述符0.1.2也会被记录

#define STDIN_FILENO  0 //标准输入的文件描述符
#define STDOUT_FILENO 1 //标准输出的文件描述符
#define STDERR_FILENO 2 //标准错误的文件描述符

当程序运行起来后打开其他文件时,系统会返回文件描述符表中最小可用的文件描述符,并把这个文件描述符记录在表中。Linux中一个进程最多智能打开1024个文件,所以当文件不再使用时要及时调用close()关闭文件

常用I/O函数

必要的头文件

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

int open(const char *pathname, int flags, mode_t mode)

  • 功能
    • 打开文件,如果文件不存在则创建
  • 参数
    • pathname: 文件的路径及文件名。
    • flags: 打开文件的行为标志,如,以只读方式(O_RDONLY,第一个为字母不是数据)打开,以读写或新建新文件的方式(O_RDWR|O_CREAT)打开。
    • mode: 这个参数,只有在文件不存在时有效,指新建文件时指定文件的权限
  • 返回值
    • 成功:成功返回打开的文件描述符
    • 失败:-1

int close(int fd)

  • 功能

    • 关闭已打开的文件
  • 参数

    • fd: 文件描述符,open()的返回值
  • 返回值

    • 成功:0
    • 失败:-1

ssize_t write(int fd, const void *addr, size_t count)

  • 功能
    • 把指定数目的数据写到文件(fd)
  • 参数
    • fd: 文件描述符
    • addr: 数据首地址
    • count: 写入数据的长度(字节),一般情况下,数据有多少,就往文件里写多少,不能多也不能少
  • 返回值
    • 成功:实际写入数据的字节个数
    • 失败:-1

ssize_t read(int fd, void *addr, size_t count)

  • 功能
    • 把指定数目的数据读到内存(缓冲区)
  • 参数
    • fd: 文件描述符
    • addr: 内存首地址
    • count: 读取的字节个数
  • 返回值
    • 成功:实际读取到的字节个数
    • 失败:-1

案例

Linux cp 命令简单实现

/*   ./cp src.c des.c      */
#include "stdio.h"
#include "unistd.h"
#include "fcntl.h"
#include "string.h"
int main(int argc, char *argv[])
{
    int src_fd, des_fd;
    char read_buff[128] = {0};
    int src_ret = 0;
    if (argc < 3)
    {
        printf("please input src & des file\n");
        return -1;
    }
    src_fd = open(argv[1], O_RDONLY);
    if (src_fd < 0)
    {
        printf("open src file \n");
        return -1;
    }
    printf("open src file ok id:%d\n", src_fd);
    des_fd = open(argv[2], O_CREAT | O_WRONLY, 0777);// 创建传参进来的文件名 并权限为777
    if (des_fd < 0)
    {
        printf("open des file \n");
        return -1;
    }
    printf("open des file ok id:%d\n", des_fd);
    while (1)
    {
        src_ret = read(src_fd, read_buff, 128);
        if (src_ret < 128)
            break;
        write(des_fd, read_buff, src_ret);
        memset(read_buff, 0, 128);
    }
    write(des_fd, read_buff, src_ret);
    close(src_fd);
    close(des_fd);
    return 0;
}

运行代码前先创建一个src.c文件并写入525byte

./cp src.c des.c

在这里插入图片描述
在这里插入图片描述

可以看到des.c字节数和src.c字节数相同

我们可以看到我们创建的权限为777 但结果只有775

这是因为Linux中有个叫 umask 默认权限的值

umask

在这里插入图片描述

文件I/O

大多数Linux文件I/O只需要5个函数 open read write close lseek

现在说下lseek

  • 每个打开文件都有一个与其相关联的“当前文件位移量”。它是一个非负整数,用以度量从文件开始处计算的字节数。就是改变文件描述符的偏移位置。

off_t lseek(int fildes, off_t offset, int whence)

  • whence:
    SEEK_SET : 把偏移量设为offset, 从文件头开始.
    SEEK_CUR : 把当前偏移量加上offset的值
    SEEK_END : 先从文件尾开始偏移offset的值
  • 返回值:成功返回定位之后的文件指针偏移 失败返回 -1

案例

#include "stdio.h"
#include "unistd.h"
#include "fcntl.h"

int main(int argc, char *argv[])
{
    int fd;
    char write_buf[] = "hello linux";
    char read_buf[128] = {0};
    fd = open("./a.c", O_RDWR | O_TRUNC);
    if (fd < 0)
    {
        printf("open file a.c ail\n");
        return -1;
    }
    printf("open file a.c success fd:%d\n", fd);
    write(fd, write_buf, sizeof(write_buf)); 
    lseek(fd, 0, SEEK_SET);//把偏移量设为offset, 从文件头开始 偏移0个int单位
    read(fd, read_buf, 128);
    printf("read_buff = %s\n", read_buf);
    close(fd);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值