扫描文件夹中的文件

scandir()

该函数能有顺序的扫描文件夹的文件列表。其申明如下:

1
2
3
4
5
6
#include <dirent.h>
int scandir(const char *dirp, struct dirent ***namelist,
int (*filter)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **));
int alphasort(const void *a, const void *b);
int versionsort(const void *a, const void *b);

使用demo:

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
// example
int fileNameFilter(const struct dirent *cur) {
std::string str(cur->d_name);
if (str.find(".png") != std::string::npos) {
return 1;
}
return 0;
}

void deleteNFiles(const std::string &vDir, const int vNum) {
if (vDir.empty()) {
return;
}
int num = vNum;
struct stat s;
lstat(vDir.c_str(), &s);
if (!S_ISDIR(s.st_mode)) {
// LOG_WARN("{} is not a valid directory.", vDir);
return;
}

struct dirent **files;
int count;
count = scandir(vDir.c_str(), &files, fileNameFilter, alphasort);

for (int i = 0; i < count && num > 0; ++i) {
// char szChild[256] = {0};
// sprintf(szChild, "%s/%s", vDir, files[i]->d_name);
std::string path = vDir + "/";
path.append(std::string(files[i]->d_name));
if (files[i]->d_type != 0x08) {
continue;
}
lstat(path.c_str(), &s);
if (0 == remove(path.c_str())) {
num--;
}
}
free(files);
}

readdir()

该函数读取文件没有顺序。

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
void deleteNFiles(const std::string &vDir, const int vNum) {
if (vDir.empty()) {
return;
}
int num = vNum;
struct stat s;
lstat(vDir.c_str(), &s);
if (!S_ISDIR(s.st_mode)) {
// LOG_WARN("{} is not a valid directory.", vDir);
return;
}

DIR *pDir = opendir(vDir.c_str());
if (nullptr == pDir) {
return;
}
struct dirent *filename;
while ((filename = readdir(pDir)) != nullptr && num > 0) {
LOG_INFO("file: {}", filename->d_name);
if (strcmp(filename->d_name, ".") == 0 || strcmp(filename->d_name, "..") == 0) {
continue;
}
char szChild[256] = {0};
sprintf(szChild, "%s/%s", vDir.c_str(), filename->d_name);
if (filename->d_type != 0x8) { // not file
continue;
}
lstat(szChild, &s);
if (0 == remove(szChild)) {
num--;
}
}
}

文件夹

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>

// 创建路径
int32_t CreateDirectory(const std::string &dir)
{
uint32_t dir_path_len = dir.length();
if (dir_path_len > MAX_PATH_LEN)
{
return -1;
}
char tmp_dir_path[MAX_PATH_LEN] = {0};
for (uint32_t i = 0; i < dir_path_len; ++i)
{
tmp_dir_path[i] = dir[i];
if (tmp_dir_path[i] == '/')
{
if (access(tmp_dir_path, 0) != 0)
{
int32_t ret = mkdir(tmp_dir_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret != 0)
{
return ret;
}
}
}
}
return 0;
}

// 删除指定路径
int RemoveDirectory(const std::string &path)
{
DIR *dirp = opendir(path.c_str());
if (!dirp)
{
return -1;
}
struct dirent *dir;
struct stat st;
while ((dir = readdir(dirp)) != NULL)
{
if (strcmp(dir->d_name, ".") == 0 || strcmp(dir->d_name, "..") == 0)
{
continue;
}
std::string sub_path = path + '/' + dir->d_name;
if (lstat(sub_path.c_str(), &st) == -1)
{
continue;
}
if (S_ISDIR(st.st_mode))
{
if (RemoveDirectory(sub_path) == -1)
{
closedir(dirp);
return -1;
}
rmdir(sub_path.c_str());
}
else if (S_ISREG(st.st_mode))
{
unlink(sub_path.c_str());
}
else
{
continue;
}
}
if (rmdir(path.c_str()) == -1)
{
closedir(dirp);
return -1;
}
closedir(dirp);
return 0;
}

int32_t Remove(const std::string &path)
{
if (access(path.c_str(), 0) != 0)
{
return 0;
}

struct stat st;
if (lstat(path.c_str(), &st) == -1)
{
return -1;
}
if (S_ISREG(st.st_mode))
{
if (unlink(path.c_str()) == -1)
{
return -1;
}
}
else if (S_ISDIR(st.st_mode))
{
if (path == "." || path == "..")
{
return -1;
}
if (RemoveDirectory(path) == -1)
{
return -1;
}
}
return 0;
}

// 查询文件是否存在
bool IsFileExist(const std::string &path)
{
return access(path.c_str(), 0) == 0;
}

// 列出指定路径中的所有文件名
std::vector<std::string> ListFilename(const std::string &dir)
{
std::vector<std::string> files;

struct dirent *filename;
DIR *file_dir;
file_dir = opendir(dir.c_str());
if (nullptr == file_dir)
{
return files;
}

/* read all the files in the dir ~ */
while ((filename = readdir(file_dir)) != nullptr)
{
// get rid of "." and ".."
if (strcmp(filename->d_name, ".") == 0 || strcmp(filename->d_name, "..") == 0 ||
filename->d_type == 4)
continue;
files.push_back(filename->d_name);
}

return files;
}

分块读写大文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void demo() 
{
int64_t size = 1024 * 1024 * 10;
char *buf = new char[size];
std::ifstream in("1.jpg", std::ios::in | std::ios::binary);
std::ofstream out("a.jpg", std::ios::out | std::ios::binary);
if (!in.is_open() || !out.is_opent())
{
return;
}
while (!in.eof())
{
std::streamsize len = in.read(buf, size).gcount();
out.write(buf, len);
// out << std::string(buf, len);
}
in.close();
out.close();
}