Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

1. 关键词

C++ 文件系统操作 读取纯文本文件 写入纯文本文件 跨平台

2. fileutil.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

#pragma once

#include <string>
#include <cstdio>
#include <cstdint>
#include "filetype.h"
#include "filepath.h"

namespace cutl
{

/**
* @brief The file guard class to manage the FILE pointer automatically.
* file_guard object can close the FILE pointer automatically when his scope is exit.
*/
class file_guard
{
public:
/**
* @brief Construct a new file guard object
*
* @param file the pointer of the FILE object
*/
explicit file_guard(FILE *file);

/**
* @brief Destroy the file guard object
*
*/
~file_guard();

/**
* @brief Get the FILE pointer.
*
* @return FILE*
*/
FILE *getfd() const;

private:
FILE *file_;
};

/**
* @brief Read the text content of a file.
*
* @param path the filepath of the file to be read
* @param max_read_size the maximum size to be read, default is 4096 bytes.
*
* If the file size is larger than max_read_size, only the first max_read_size bytes will be read. otherwise, the whole file will be read.
*
* @return text content of the file
*/
std::string readtext(const filepath &path, uint64_t max_read_size = 4096);

/**
* @brief Write the text content to a file.
*
* @param path the filepath of the file to be written
* @param content text content to be written to the file
* @return true if the content is written successfully, false otherwise.
*/
bool writetext(const filepath &path, const std::string &content);

} // namespace cutl

3. fileutil.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <cstdio>
#include <map>
#include <iostream>
#include <cstring>
#include <sys/stat.h>
#include "fileutil.h"
#include "inner/logger.h"
#include "inner/filesystem.h"
#include "strutil.h"

namespace cutl
{
file_guard::file_guard(FILE *file)
: file_(file)
{
}

file_guard::~file_guard()
{
if (file_)
{
// CUTL_DEBUG("close file");
int ret = fclose(file_);
if (ret != 0)
{
CUTL_ERROR("fail to close file, ret" + std::to_string(ret));
}
file_ = nullptr;
}
// ROBOLOG_DCHECK(file_ == nullptr);
}

FILE *file_guard::getfd() const
{
return file_;
}

std::string readtext(const filepath &path, uint64_t max_read_size)
{
file_guard fg(fopen(path.str().c_str(), "r"));
if (fg.getfd() == nullptr)
{
CUTL_ERROR("open file failed for " + path.str());
return "";
}

// 从文件系统的文档信息里读取文件大小,性能更高
auto data_len = filesize(path, true);
// 公国文件操作的方式和获取文件大小
// fseek(fg.getfd(), 0, SEEK_END);
// size_t data_len = static_cast<size_t>(ftell(fg.getfd()));
// rewind(fg.getfd());
CUTL_DEBUG("file size: " + std::to_string(data_len) + ", file: " + path.str());

// get read size
if (data_len > max_read_size)
{
data_len = max_read_size;
CUTL_WARN("file size is large than " + std::to_string(max_read_size) + ", file:" + path.str());
}

char *buffer = new char[data_len + 1];
if (buffer == nullptr)
{
CUTL_ERROR("buffer alloc failed, data_len:" + std::to_string(data_len));
return "";
}
size_t read_len = static_cast<size_t>(fread(buffer, 1, data_len, fg.getfd()));
if (read_len < data_len)
{
CUTL_ERROR("read file failed, only read " + std::to_string(read_len) + " bytes for " + path.str());
}

buffer[read_len] = '\0';
auto text = std::string(buffer);
delete[] buffer;

return text;
}

// https://en.cppreference.com/w/cpp/header/cstdio
bool writetext(const filepath &path, const std::string &content)
{
// std::lock_guard
file_guard fg(fopen(path.str().c_str(), "w"));
if (fg.getfd() == nullptr)
{
CUTL_ERROR("open file failed for " + path.str() + ", error: " + strerror(errno));
return false;
}

size_t written_size = fwrite(content.c_str(), 1, content.length(), fg.getfd());
if (written_size != content.length())
{
CUTL_ERROR("written size is not equal to content size for " + path.str());
return false;
}

int ret = fflush(fg.getfd());
if (0 != ret)
{
CUTL_ERROR("fail to flush file:" + path.str());
return false;
}

if (!file_sync(fg.getfd()))
{
CUTL_ERROR("file_sync failed for " + path.str());
return false;
}

return true;
}

4. 源码地址

更多详细代码,请查看本人写的C++ 通用工具库: common_util, 本项目已开源,代码简洁,且有详细的文档和Demo。

推荐阅读
C++文件系统操作1 - 跨平台实现文件的创建和删除 C++文件系统操作1 - 跨平台实现文件的创建和删除 C++文件系统操作6 - 跨平台实现查找指定文件夹下的特定文件 C++文件系统操作6 - 跨平台实现查找指定文件夹下的特定文件 C++文件系统操作4 - 跨平台实现获取文件|文件夹的大小 C++文件系统操作4 - 跨平台实现获取文件|文件夹的大小

评论