c - 将目录中的文件列表读入char数组
问题描述
我正在尝试使用一些字符串格式获取目录中的文件列表。目前,像这样。
#define BUFFER 4096
void ListDir(){
WIN32_FIND_DATA data;
HANDLE hFind;
hFind = FindFirstFile("*", &data);
char* dir = calloc(1, BUFFER);
if (hFind != INVALID_HANDLE_VALUE)
{
snprintf(dir, BUFFER, "RHPDIR<>%s\n", cDir());
do {
int len = strlen(dir);
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
snprintf(dir + len, sizeof(dir) - len, "[DIRECTORY] %s\n", data.cFileName);
}
else {
ULONGLONG FileSize = data.nFileSizeHigh;
FileSize <<= sizeof(data.nFileSizeHigh) * 8;
FileSize |= data.nFileSizeLow;
snprintf(dir + len, sizeof(dir) - len, "[FILE] %s (%llu bytes)\n", data.cFileName, FileSize);
}
} while (FindNextFile(hFind, &data));
sockSend(dir);
if (dir)
{
free(dir);
}
}
}
问题是读取文件较多的目录,尤其是 System32 等大目录,缓冲区溢出。我知道我需要增加dir
. 但我不明白我怎么能做到这一点。
目标:从任何目录获取包含所有文件和目录的缓冲区
我试过的:我觉得这是一个不好的方法,但我试过这个希望它能奏效。我制作了一个返回目录列表大小的函数,并使用该大小创建缓冲区。这适用于大多数目录,但仍然在 System32 目录中,我遇到了溢出。我也不得不为此扫描目录两次。:秒
int returnCurrentDirFilesize()
{
WIN32_FIND_DATA data;
HANDLE hFind;
hFind = FindFirstFile("*", &data);
int size = 0;
char tmpbuf[BUFFER];
if (hFind != INVALID_HANDLE_VALUE)
{
snprintf(tmpbuf, BUFFER, "RHPDIR<>%s\n", cDir());
size += strlen(tmpbuf);
do {
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
memset(tmpbuf, '\0', BUFFER);
snprintf(tmpbuf, BUFFER, "[DIRECTORY] %s\n", data.cFileName);
size += strlen(tmpbuf);
}
else {
ULONGLONG FileSize = data.nFileSizeHigh;
FileSize <<= sizeof(data.nFileSizeHigh) * 8;
FileSize |= data.nFileSizeLow;
memset(tmpbuf, '\0', BUFFER);
snprintf(tmpbuf, BUFFER, "[FILE] %s (%llu bytes)\n", data.cFileName, FileSize);
size += strlen(tmpbuf);
}
} while (FindNextFile(hFind, &data));
return size;
}
}
void ListDir(){
WIN32_FIND_DATA data;
HANDLE hFind;
hFind = FindFirstFile("*", &data);
char* dir = calloc(1, BUFFER);
if (hFind != INVALID_HANDLE_VALUE)
{
snprintf(dir, BUFFER, "RHPDIR<>%s\n", cDir());
do {
int len = strlen(dir);
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
snprintf(dir + len, sizeof(dir) - len, "[DIRECTORY] %s\n", data.cFileName);
}
else {
ULONGLONG FileSize = data.nFileSizeHigh;
FileSize <<= sizeof(data.nFileSizeHigh) * 8;
FileSize |= data.nFileSizeLow;
snprintf(dir + len, sizeof(dir) - len, "[FILE] %s (%llu bytes)\n", data.cFileName, FileSize);
}
} while (FindNextFile(hFind, &data));
sockSend(dir);
if (dir)
{
free(dir);
}
}
}
解决方案
您可以使用 realloc 函数来完成此操作。我在下面编辑了您的代码,以向您展示如何使用以完成此操作
#define BUFFER 4096
void ListDir()
{
WIN32_FIND_DATAA data;
HANDLE hFind;
hFind = FindFirstFileA("C:\\windows\\system32\\*", &data);
char* dir = calloc(BUFFER, sizeof(char));
size_t dirSize = BUFFER;
size_t dirIndex = 0;
if (hFind != INVALID_HANDLE_VALUE)
{
snprintf(dir, BUFFER, "RHPDIR<>%s\n", "C:\\windows\\system32\\");
dirIndex = strlen(dir);
do {
size_t currLineSize = 0;
char currLine[MAX_PATH * 2] = { '\0' };
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
snprintf(currLine, sizeof(currLine), "[DIRECTORY] %s\n", data.cFileName);
}
else {
ULONGLONG FileSize = data.nFileSizeHigh;
FileSize <<= sizeof(data.nFileSizeHigh) * 8;
FileSize |= data.nFileSizeLow;
snprintf(currLine, sizeof(currLine), "[FILE] %s (%llu bytes)\n", data.cFileName, FileSize);
}
// here we check if our memory is enough to store new line or not
// if not, reallocate buffer with a new size
currLineSize = strlen(currLine);
if (dirIndex + currLineSize + sizeof(char) >= dirSize) {
char* tmp = dir;
dirSize += BUFFER;
dir = realloc(dir, dirSize);
if (dir == NULL) {
// allocation error
free(tmp);
exit(1);
}
}
strcat_s(dir, dirSize, currLine);
dirIndex += currLineSize;
} while (FindNextFileA(hFind, &data));
// sockSend(dir);
printf("%s", dir);
if (dir)
{
free(dir);
}
}
}
推荐阅读
- r - 根据结果提取值
- python - 从蛇游戏中的随机食物中排除蛇的坐标
- javascript - 不和谐的机器人可以计算用户在个人资料上得到多少反应吗?
- python - 有人可以帮我理解这个逻辑吗?
- javascript - 我如何能够在 Javascript 中的数组中添加一个键?幕后发生了什么
- java - JMeter - Function Helper 的参数面板隐藏超过 2 个参数的参数
- javascript - 垃圾邮件提交按钮以导入 CSV 文件
- excel - vba excel属性是否可以返回word.range?
- java - Java(jdk/jre) 64 位是否支持 32 位应用程序?
- javascript - 如何将只读输入字段的值相乘并将结果显示在另一个字段中