Linux环境下使用C语言统计目录及其子目录文件数量的技术问询
递归统计Linux目录及子目录文件总数的C实现
Hey Jesse, I totally get the frustration—most quick hits online only cover single-directory counts, but recursive counting requires a bit more work. Let's build a solution step by step using standard Linux system calls.
The core idea is to traverse each directory recursively: for every entry in a directory, check if it's a regular file (count it) or a subdirectory (dive in and repeat). We'll use Linux's directory manipulation functions (opendir, readdir, closedir) and stat to check file types.
Complete Working Code
#include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <sys/stat.h> #include <string.h> // Recursive function to count files long long count_files(const char *dir_path) { long long count = 0; DIR *dir = opendir(dir_path); struct dirent *entry; struct stat stat_buf; char full_path[PATH_MAX]; if (!dir) { fprintf(stderr, "Warning: Could not open directory %s\n", dir_path); return 0; } while ((entry = readdir(dir)) != NULL) { // Skip the special "." and ".." directories to avoid infinite loops if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } // Build the full path of the entry snprintf(full_path, sizeof(full_path), "%s/%s", dir_path, entry->d_name); // Get file status to determine type if (stat(full_path, &stat_buf) == -1) { fprintf(stderr, "Warning: Could not stat %s\n", full_path); continue; } if (S_ISREG(stat_buf.st_mode)) { // It's a regular file—increase count count++; } else if (S_ISDIR(stat_buf.st_mode)) { // It's a subdirectory—recursively count its files count += count_files(full_path); } // Note: We're skipping symlinks, devices, pipes, etc. Adjust if needed } closedir(dir); return count; } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <directory_path>\n", argv[0]); return EXIT_FAILURE; } long long total = count_files(argv[1]); printf("Total regular files: %lld\n", total); return EXIT_SUCCESS; }
Key Breakdowns
- Recursive Function:
count_filestakes a directory path, opens it, and iterates over every entry. For each entry:- We skip
.(current directory) and..(parent directory) to avoid looping infinitely. - We build the full path of the entry (since
readdironly returns the filename, not the full path). statgives us detailed info about the file—we useS_ISREGto check for regular files, andS_ISDIRto detect subdirectories.
- We skip
- Error Handling: We add warnings for unopenable directories or unstatable files (common if you don't have permission for some subdirectories).
- Symlinks & Special Files: The code skips symlinks, devices, and other non-regular files. If you want to count symlinks as files, add a check for
S_ISLNKand increment the count.
Compile & Run
Save the code as count_files.c, then compile with:
gcc count_files.c -o count_files
Run it with your target directory:
./count_files /path/to/your/directory
Notes
- The use of
long longensures we don't hit integer overflow if you're counting thousands/millions of files. - If you need to count other file types (like symlinks or directories themselves), adjust the conditional checks with other
S_IS*macros (e.g.,S_ISLNKfor symlinks).
内容的提问来源于stack exchange,提问作者Jesse
相关产品推荐
相关产品推荐

