文件系统核心存储引擎_实现(二)

内存映射实战之文件操作父类头文件定义

在这里插入图片描述

#ifndef QINIU_LARGE_FILE_OP_H_
#define QINIU_LARGE_FILE_OP_H_

#include "common.h"

namespace qiniu
{
    namespace largefile
    {
        class FileOperation
        {
            public:
            FileOperation(const std::string &file_name, const int open_fags = O_RDWR | O_LARGEFILE);
            ~FileOperation();

            int open_file();
            void close_file();

            int flush_file(); /* 把文件立即写入到磁盘 */

            int unlink_file();

            int pread_file(char *buf, const int32_t nbytes, const int64_t offset);
            int pwrite_file(const char *buf, const int32_t nbytes, const int64_t offset);

            int write_file(const char *buf, const int32_t nbytes);

            int64_t get_file_size();

            int ftruncate_file(const int64_t length);
            int seek_file(const int64_t offset);

            int get_fd() const
            {
                return fd_;
            }

            protected:
            int fd_;
            int open_fags_;
            char *file_name_;

            protected:
            int check_file();

            protected:
            static const mode_t OPEN_MODE = 0644; /* 0: 八进制 */
            static const int MAX_DISK_TIMES = 5;
        };
    }
}
#endif /* */

内存映射实战之文件操作CPP实现(上)

在这里插入图片描述

#include "file_op.h"
#include "common.h"

namespace qiniu
{
    namespace largefile
    {
        FileOperation::FileOperation(const std::string &file_name, const int open_fags):
        fd_(-1), open_fags_(open_fags)
        {
            file_name_ = strdup(file_name.c_str()); /* strdup() 动态内存分配记得要释放 */
        }

        FileOperation::~FileOperation()
        {
            if (fd_ > 0)
            {
                ::close(fd_);
            }

            if (NULL != file_name_)
            {
                free(file_name_); /* 释放第11行strdup()的动态内存分配 */
                file_name_ = NULL;
            }
        }

        int FileOperation::open_file()
        {
            if (fd_ > 0)
            {
                close(fd_);
                fd_ = -1;
            }

            fd_ = ::open(file_name_, open_fags_, OPEN_MODE);
            if (fd_ < 0)
            {
                return -errno;
            }

            return fd_;
        }

        void FileOperation::close_file()
        {
            if (fd_ < 0)
            {
                return;
            }

            ::close(fd_);
            fd_ = -1;
        }

        int64_t FileOperation::get_file_size() /* 获取文件的大小 */
        {
            int fd = check_file();

            if (fd < 0)
            {
                return -1;
            }

            struct stat statbuf;
            if (fstat(fd, &statbuf) != 0)
            {
                return -1;
            }

            return statbuf.st_size;
        }

        int FileOperation::check_file()
        {
            if (fd_ < 0)
            {
                fd_ = open_file();
            }

            return fd_;
        }

        int FileOperation::ftruncate_file(const int64_t length)
        {
            int fd = check_file();

            if (fd < 0)
            {
                return -fd;
            }

            return ftruncate(fd, length);
        }

        int FileOperation::seek_file(const int64_t offset)
        {
            int fd = check_file();

            if (fd < 0)
            {
                return fd;
            }

            return lseek(fd, offset, SEEK_SET);
        }

        int FileOperation::flush_file() /* 把文件立即写入到磁盘 */
        {
            if (open_fags_ & O_SYNC) /* O_SYNC 同步 */
            {
                return 0;
            }

            int fd = check_file();
            if (fd < 0)
            {
                return fd;
            }

            return fsync(fd);
        }

        int FileOperation::unlink_file()
        {
            close_file();
            return ::unlink(file_name_);
        }

        int FileOperation::pread_file(char *buf, const int32_t nbytes, const int64_t offset)
        {
            int32_t left = nbytes;
            int64_t read_offset = offset;
            int32_t read_len = 0;
            char *p_tmp = buf;

            int i = 0;

            while (left > 0)
            {
                ++i;

                if (i >= MAX_DISK_TIMES)
                {
                    break;
                }

                if (check_file() < 0)
                {
                    return -errno;
                }

                read_len = ::pread64(fd_, p_tmp, left, read_offset);

                if (read_len < 0)
                {
                    read_len = -errno;

                    if (-read_len == EINTR || EAGAIN == -read_len)
                    {
                        continue;
                    }
                    else if (EBADF == -read_len)
                    {
                        fd_ = -1;
                        continue;
                    }
                    else if (EBADF == -read_len)
                    {
                        fd_ = -1;
                        return read_len;
                    }else
                    {
                        return read_len;
                    }
                }
                else if (0 == read_len)
                {
                    break;
                }
                left -= read_len;
                p_tmp += read_len;
                read_offset += read_len;

                if (0 != left)
                {
                    return EXIT_DISK_OPER_INCOMPLETE;
                }

                return TFS_SUCCESS;
            }  
        }

        int FileOperation::pwrite_file(const char *buf, const int32_t nbytes, const int64_t offset)
        {
            int32_t left = nbytes;
            int64_t write_offset = offset;
            int32_t written_len = 0;
            const char *p_tmp = buf;

            int i = 0;

            while (left > 0)
            {
                ++i;

                if (i >= MAX_DISK_TIMES)
                {
                    break;
                }

                if (check_file() < 0)
                {
                    return -errno;
                }

                written_len = ::pwrite64(fd_, p_tmp, left, write_offset);

                if (written_len < 0)
                {
                    written_len = -errno;

                    if (-written_len == EINTR || EAGAIN == -written_len)
                    {
                        continue;
                    }
                    else if (EBADF == -written_len)
                    {
                        fd_ = -1;
                        continue;
                    }
                    else
                    {
                        return written_len;
                    } 
                }
                else if (0 == written_len)
                {
                    break;
                }

                left -= written_len;
                p_tmp += written_len;
                write_offset += written_len;

                if (0 != left)
                {
                    return EXIT_DISK_OPER_INCOMPLETE;
                }

                return TFS_SUCCESS;
            }  
        }

        int FileOperation::write_file(const char *buf, const int32_t nbytes)
        {
            int32_t left = nbytes;
            int32_t written_len = 0;
            const char *p_tmp = buf;

            int i = 0;

            while (left > 0)
            {
                ++i;

                if (i >= MAX_DISK_TIMES)
                {
                    break;
                }

                if (check_file() < 0)
                {
                    return -errno;
                }

                written_len = ::write(fd_, p_tmp, left);

                if (written_len < 0)
                {
                    written_len = -errno;

                    if (-written_len == EINTR || EAGAIN == -written_len)
                    {
                        continue;
                    }
                    else if (EBADF == -written_len)
                    {
                        fd_ = -1;
                        return written_len;
                    }
                    else
                    {
                        return written_len;
                    }   
                }
                else if (0 == written_len)
                {
                    break;
                }

                left -= written_len;
                p_tmp += written_len;
            }
        }
    }
}

内存映射实战之文件操作CPP实现(中)

在这里插入图片描述

#ifndef _COMMON_H_INCLUDED_
#define _COMMON_H_INCLUDED_

#include <iostream>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <string.h>
#include <stdint.h>
#include <errno.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>

namespace qiniu
{
    namespace largefile
    {
        const int32_t TFS_SUCCESS = 0;
        const int32_t EXIT_DISK_OPER_INCOMPLETE = -8012; /* read or write length is less than required */
    }
}

#endif /* _COMMON_H_INCLUDED_ */

在这里插入图片描述

#include "file_op.h"
#include "common.h"

using namespace std;
using namespace qiniu;

int main(void)
{
    const char *filename = "file_op.txt";
    largefile::FileOperation *fileOP = new largefile::FileOperation(filename, O_CREAT | O_RDWR | O_LARGEFILE);

    int fd = fileOP->open_file();
    if (fd < 0)
    {
        fprintf(stderr, "open file %s failed. reason: %s \n", filename, strerror(-fd));
        exit(1);
    }

    char buffer[4096];
    memset(buffer, '6', 4096);
    int ret = fileOP->pwrite_file(buffer, 4096, 1024);
    if (ret < 0)
    {
        fprintf(stderr, "pwrite file %s failed reason: %s\n", filename, strerror(-ret));
    }

    fileOP->close_file();

    return 0;
}

demo(一)测试运行结果:

在这里插入图片描述

more file_op.txt

在这里插入图片描述

demo(二)测试运行结果:

在这里插入图片描述

#include "file_op.h"
#include "common.h"

using namespace std;
using namespace qiniu;

int main(void)
{
    const char *filename = "file_op.txt";
    largefile::FileOperation *fileOP = new largefile::FileOperation(filename, O_CREAT | O_RDWR | O_LARGEFILE);

    int fd = fileOP->open_file();
    if (fd < 0)
    {
        fprintf(stderr, "open file %s failed. reason: %s \n", filename, strerror(-fd));
        exit(1);
    }

    char buffer[64+1];
    memset(buffer, '8', 64);
    int ret = fileOP->pwrite_file(buffer, 64, 1024);
    if (ret < 0)
    {
        fprintf(stderr, "pwrite file %s failed reason: %s\n", filename, strerror(-ret));
    }

    memset(buffer, 0, 64);
    ret = fileOP->pread_file(buffer, 64, 1024);
    if (ret < 0)
    {
        fprintf(stderr, "pread file %s failed reason %s \n", filename, strerror(-ret));
    }
    else
    {
        buffer[64] = '\0';
        printf("read: %s \n", buffer);
    }
    

    fileOP->close_file();

    return 0;
}

运行结果:
在这里插入图片描述

demo(三)测试运行结果:

在这里插入图片描述

#include "file_op.h"
#include "common.h"

using namespace std;
using namespace qiniu;

int main(void)
{
    const char *filename = "file_op.txt";
    largefile::FileOperation *fileOP = new largefile::FileOperation(filename, O_CREAT | O_RDWR | O_LARGEFILE);

    int fd = fileOP->open_file();
    if (fd < 0)
    {
        fprintf(stderr, "open file %s failed. reason: %s \n", filename, strerror(-fd));
        exit(1);
    }


    char buffer[64+1];
    memset(buffer, '8', 64);
    int ret = fileOP->pwrite_file(buffer, 64, 1024);
    if (ret < 0)
    {
        if (ret == largefile::EXIT_DISK_OPER_INCOMPLETE)
        {
            fprintf(stderr, "pwrite_file: read length is less than required!");
        }
        else
        {
            fprintf(stderr, "pwrite file %s failed reason: %s\n", filename, strerror(-ret));
        } 
    }


    memset(buffer, 0, 64);
    ret = fileOP->pread_file(buffer, 64, 1024);
    if (ret < 0)
    {
        if (ret == largefile::EXIT_DISK_OPER_INCOMPLETE)
        {
            fprintf(stderr, "pread_file: read length is less than required!");
        }else
        {
            fprintf(stderr, "pread file %s failed reason %s \n", filename, strerror(-ret));
        } 
    }
    else
    {
        buffer[64] = '\0';
        printf("read: %s \n", buffer);
    }


    memset(buffer, '9', 64);
    ret = fileOP->write_file(buffer, 64);
    if (ret < 0)
    {
        if (ret == largefile::EXIT_DISK_OPER_INCOMPLETE)
        {
            fprintf(stderr, "write_file: read length is less than requirend!");
        }
        else
        {
            fprintf(stderr, "write_file %s failed reason: %s\n", filename, strerror(-ret));
        }
    }
    

    fileOP->close_file();

    return 0;
}

运行结果:

在这里插入图片描述

more file_op.txt

在这里插入图片描述

总结:

文件的指针不变, 因此插入的字符, 还是在头部开始

demo(四)测试运行结果:

在这里插入图片描述

#include "file_op.h"
#include "common.h"

using namespace std;
using namespace qiniu;

int main(void)
{
    const char *filename = "file_op.txt";
    largefile::FileOperation *fileOP = new largefile::FileOperation(filename, O_CREAT | O_RDWR | O_LARGEFILE);

    int fd = fileOP->open_file();
    if (fd < 0)
    {
        fprintf(stderr, "open file %s failed. reason: %s \n", filename, strerror(-fd));
        exit(1);
    }


    char buffer[64+1];
    memset(buffer, '8', 64);
    int ret = fileOP->pwrite_file(buffer, 64, 128);
    if (ret < 0)
    {
        if (ret == largefile::EXIT_DISK_OPER_INCOMPLETE)
        {
            fprintf(stderr, "pwrite_file: read length is less than required!");
        }
        else
        {
            fprintf(stderr, "pwrite file %s failed reason: %s\n", filename, strerror(-ret));
        } 
    }


    memset(buffer, 0, 64);
    ret = fileOP->pread_file(buffer, 64, 128);
    if (ret < 0)
    {
        if (ret == largefile::EXIT_DISK_OPER_INCOMPLETE)
        {
            fprintf(stderr, "pread_file: read length is less than required!");
        }else
        {
            fprintf(stderr, "pread file %s failed reason %s \n", filename, strerror(-ret));
        } 
    }
    else
    {
        buffer[64] = '\0';
        printf("read: %s \n", buffer);
    }


    memset(buffer, '9', 64);
    ret = fileOP->write_file(buffer, 64);
    if (ret < 0)
    {
        if (ret == largefile::EXIT_DISK_OPER_INCOMPLETE)
        {
            fprintf(stderr, "write_file: read length is less than requirend!");
        }
        else
        {
            fprintf(stderr, "write_file %s failed reason: %s\n", filename, strerror(-ret));
        }
    }
    

    fileOP->close_file();

    return 0;
}

运行结果:
在这里插入图片描述

vi file_op.tx

在这里插入图片描述

总结:

文件的指针不变, 因此插入的字符, 还是在头部开始

结语:

温馨提示: 请不要用跑步鞋和在有太阳的情况下打球, 打球, 容易扭伤, 我星期五的时候打球(好久没有和舍友打球, 拉这他们打, 外面太阳温度有点大, 因为温度太高, 所以没有打超过30分钟, 没劲.)

时间: 2020-06-20

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值