四时宝库

程序员的知识宝库

c++ 杂项 (3) 读写文件(c++file读写文件)

杂项(3)读写文件

c++ 对文件提供了流方式读写, 一般工作中都会简单地封装个读写函数,方便使用。

文件写入函数

/*
定义一个函数WriteFile,它接受四个参数:
path:要写入的文件的路径。
data:要写入的数据。
size:要写入的数据的大小(字节数)。
append:一个布尔值,表示是否在文件末尾追加数据。默认值为false,表示不追加。
*/
bool WriteFile(const char* path, const char* data, int size, bool append = false) {
    if (data == nullptr || size <= 0) {
        return false;
    }
    std::ios_base::openmode mode = append ? std::ios_base::app : std::ios_base::out;
    mode |= std::ios_base::binary;
    std::ofstream fp(path, mode);
    if (!fp.is_open()) {
        return false;
    }
    if (fp.write(data, size).fail()) {
        fp.close();
        return false;
    }
    return true;
}

文件读取函数

/*
定义一个函数ReadFile,它接受四个参数:
path:要读取的文件的路径。
data:一个引用,用于保存读取的数据。
size:要读取的数据的大小(字节数),默认值为-1,表示读取整个文件。
offset:从文件的哪个偏移量开始读取,默认值为0,表示从文件开始处读取。
*/
bool ReadFile(const char* path, std::string& data, int size = -1, int64_t offset = 0) {

    std::ifstream fp(path, std::ios_base::in | std::ios_base::binary);
    if (!fp.is_open()) {
        return false;
    }

    int64_t fileSize = fp.seekg(0, std::ios_base::end).tellg();
    if (size == -1) {
        size = (int)(fileSize - offset);
    }

    if (offset > fileSize
        || (size > 128 * 1024 * 1024)
        || (fileSize - offset < (int64_t)size)
        || offset != fp.seekg(offset, std::ios_base::beg).tellg()
        ) {
        fp.close();
        return false;
    }

    data.clear();
    char buf[4096] = { 0 };
    do {
        int per = (size > 4096) ? 4096 : size;
        if (per != fp.read(buf, per).gcount()) {
            fp.close();
            return false;
        }
        data.append(buf, per);
        size -= per;
    } while (size > 0);
    fp.close();
    return true;
}

结合下, 以一个工具类封装:

#ifndef __XX_TOOL_H__
#define __XX_TOOL_H__

#include <stdint.h>
#include <string>
#include <iostream>  
#include <fstream>  
#ifdef _WIN32
#include <windows.h>
#else
#include <time.h>
#include <unistd.h>
#endif

class XXTool {
public:

    //读取文件
    static bool ReadFile(const char* path, std::string& data, int size = -1, int64_t offset = 0) {

        std::ifstream fp(path, std::ios_base::in | std::ios_base::binary);
        if (!fp.is_open()) {
            return false;
        }
        int64_t fileSize = fp.seekg(0, std::ios_base::end).tellg();
        if (size == -1) {
            size = (int)(fileSize - offset);
        }
        if (offset > fileSize
            || (size > 128 * 1024 * 1024)
            || (fileSize - offset < (int64_t)size)
            || offset != fp.seekg(offset, std::ios_base::beg).tellg()
            ) {
            fp.close();
            return false;
        }
        data.clear();
        char buf[4096] = { 0 };
        do {
            int per = (size > 4096) ? 4096 : size;
            if (per != fp.read(buf, per).gcount()) {
                fp.close();
                return false;
            }
            data.append(buf, per);
            size -= per;
        } while (size > 0);
        fp.close();
        return true;
    }

    //写入文件
    static bool WriteFile(const char* path, const char* data, int size, bool append = false) {

        if (data == nullptr || size <= 0) {
            return false;
        }
        std::ios_base::openmode mode = append ? std::ios_base::app : std::ios_base::out;
        mode |= std::ios_base::binary;
        std::ofstream fp(path, mode);
        if (!fp.is_open()) {
            return false;
        }
        if (fp.write(data, size).fail()) {
            fp.close();
            return false;
        }
        return true;
    }
    static bool WriteFile(const char* path, const std::string& data, bool append = false) {
        return WriteFile(path, data.c_str(), data.size(), append);
    }

    //获取程序路径
    static bool GetSelfPath(std::string& path) {
        char tmp[4096] = { 0 };
#ifdef _WIN32
        if (0 >= GetModuleFileNameA(NULL, tmp, 4096)) {
            return false;
        }
#else
        if (0 >= readlink("/proc/self/exe", tmp, 4096)) {
            return false;
        }
#endif
        path = tmp;
        return true;
    }
    //注意: 字符编码问题, windows下返回的是ansi, linux下返回的是utf8
    //没有达到工业强度,应该统一处理成utf8,再输出.
    //windows下路径也应该转化成linux形式: c:\abc\a.exe => c:/abc/a.exe

    //系统运行时间
    static int64_t GetTickCount() {
#ifdef _WIN32
        return ::GetTickCount64();
#else
        struct timespec ts;
        clock_gettime(CLOCK_MONOTONIC, &ts);
        return (int64_t)(ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
#endif
    }
};

#endif

示例:

#include "XXTool.h"
#include <iostream>
int main(){
    std::string data("helloworld");
    XXTool::WriteFile("abc.txt", data);
    std::string data2;
    XXTool::ReadFile("abc.txt", data2);
    if (data == data2) {
        std::cout<<"ok"<<std::endl;
    }
    return 0;
}



发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接