c++文件持续读写

文章介绍了如何在内存受限情况下使用C++实现大文件的持续读写,通过io::bigfi类提供分块读取功能,并给出一个使用案例演示其操作。
摘要由CSDN通过智能技术生成

c++文件持续读写

通常我们读取文件的过程是直接从将整个文件内容磁盘读取到内存,但是有时候文件很大,由于内存有限甚至文件大小以及超过了可用内存大小,这时候我们就需要一段一段的持续读/写请添加图片描述

类实现(这里是一个可持续读取的实现,可持续写入就append模式多写几次啦 😃

// 大文件读取
namespace io {
class bigfi {
private:
    int fd;//目标文件描述符
    off_t size;//目标文件实际大小
    size_t buffer_size;//预留缓冲区大小
    off_t pos;//当前偏移位置,以文件开头为起点
    char* mem;//缓冲区
    ismove=false;

public:
    bigfi(const char* filepath, size_t max_buffer_size = 1 << 20, off_t offs = 0)
        : buffer_size(max_buffer_size)
        , pos(offs)
        , mem(new char[buffer_size])
    {
        struct stat st;
        if (stat(filepath, &st) < 0) throw std::logic_error("get file status failed");
        size = st.st_size;
        fd = open(filepath, O_RDONLY);
        if (fd < 0) throw std::logic_error("open file failed");
        if (pos > 0) lseek(fd, pos, SEEK_SET);
        memset(mem, 0, buffer_size);
        if (read(fd, mem, buffer_size) < 0) throw std::logic_error("read file failed");
    }
    bigfi(const bigfi&& src)
        : fd(src.fd)
        , mem(src.mem)
        , size(src.size)
        , pos(src.pos)
        , buffer_size(src.buffer_size)
    {
        src.ismove = true;
    }
    const char* c_str() const
    {
        return mem;
    }
    const size_t length() const
    {
        return size;
    }
    bigfi& operator+=(int newpos)//模拟c字符串指针计算,带边界检查
    {
        if (size <= newpos + pos | pos < -newpos) throw std::logic_error("index out of range");
        memset(mem, 0, buffer_size);
        pos += newpos;
        lseek(fd, pos, SEEK_SET);
        if (read(fd, mem, buffer_size) < 0) throw std::logic_error("read file failed");
        return *this;
    }
    bigfi& operator++()
    {
        *this += 1;
        return *this;
    }
    ~bigfi()
    {
		if (!ismove) {
            delete[] mem;
            close(fd);
        }
    }
};
}

使用案例

static const char infile[] = "test.txt";
int main()
{
    io::bigfi bf(infile, 5);
    printf("length %zu\n", bf.length());
    std::cout << bf.c_str() << std::endl;
    while (true) {//这里我们设为无限循环是为了触发边界检查
        bf += 1;
        std::cout << bf.c_str() << std::endl;
    }
}

测试结果

每次都会向后移一位,并保持最大5个字节长
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值