Praktische Implementierung
Szenarien der Dateisystemmanipulation in der Praxis
1. Datei-Such-Dienstprogramm
#include <dirent.h>
#include <stdio.h>
#include <string.h>
int search_file(const char *directory, const char *target) {
DIR *dir;
struct dirent *entry;
dir = opendir(directory);
if (dir == NULL) {
perror("Verzeichnis konnte nicht geöffnet werden");
return -1;
}
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, target) == 0) {
printf("Datei gefunden: %s\n", target);
closedir(dir);
return 0;
}
}
closedir(dir);
printf("Datei nicht gefunden\n");
return 1;
}
Strategien zur Verzeichnisdurchquerung
Rekursive Verzeichnissuche
graph TD
A[Start Verzeichnisdurchsuchung] --> B{Ist es ein Verzeichnis?}
B --> |Ja| C[Rekursive Suche in Unterverzeichnissen]
B --> |Nein| D[Datei verarbeiten]
C --> E[Suche wiederholen]
Rekursive Implementierung
void recursive_directory_scan(const char *path) {
DIR *dir;
struct dirent *entry;
char full_path[1024];
dir = opendir(path);
if (dir == NULL) {
perror("Verzeichnis kann nicht geöffnet werden");
return;
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
if (strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, "..") != 0) {
snprintf(full_path, sizeof(full_path),
"%s/%s", path, entry->d_name);
printf("Verzeichnis durchsuchen: %s\n", full_path);
recursive_directory_scan(full_path);
}
} else {
printf("Datei: %s\n", entry->d_name);
}
}
closedir(dir);
}
Erweiterte Verzeichnisoperationen
Erkennung des Dateityps
Dateityp |
Beschreibung |
DT_REG |
Reguläre Datei |
DT_DIR |
Verzeichnis |
DT_LNK |
Symbolischer Link |
DT_FIFO |
Named Pipe |
DT_SOCK |
Socket |
Umfassender Dateiklassifizierer
void classify_files(const char *directory) {
DIR *dir;
struct dirent *entry;
dir = opendir(directory);
if (dir == NULL) {
perror("Fehler beim Öffnen des Verzeichnisses");
return;
}
while ((entry = readdir(dir)) != NULL) {
switch (entry->d_type) {
case DT_REG:
printf("Reguläre Datei: %s\n", entry->d_name);
break;
case DT_DIR:
printf("Verzeichnis: %s\n", entry->d_name);
break;
case DT_LNK:
printf("Symbolischer Link: %s\n", entry->d_name);
break;
}
}
closedir(dir);
}
- Minimieren Sie wiederholte Systemrufe.
- Verwenden Sie effiziente Pufferallokation.
- Implementieren Sie Fehlerprüfungen.
- Schließen Sie Verzeichnisströme umgehend.
LabEx Empfehlung
LabEx bietet interaktive Umgebungen, um erweiterte Verzeichnismanipulationstechniken zu üben und die Systemprogrammierkenntnisse zu verbessern.
Best Practices
- Bearbeiten Sie die Speicherallokation sorgfältig.
- Implementieren Sie umfassende Fehlerprüfungen.
- Verwenden Sie geeignete Puffergrößen.
- Schließen Sie Ressourcen nach Verwendung.
- Berücksichtigen Sie die Auswirkungen auf die Leistung.
Beispiel für ein komplexes Szenario
Verzeichnisgrößenberechner
long calculate_directory_size(const char *path) {
DIR *dir;
struct dirent *entry;
long total_size = 0;
char full_path[1024];
struct stat file_stat;
dir = opendir(path);
if (dir == NULL) {
perror("Verzeichnis kann nicht geöffnet werden");
return -1;
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_REG) {
snprintf(full_path, sizeof(full_path),
"%s/%s", path, entry->d_name);
if (stat(full_path, &file_stat) == 0) {
total_size += file_stat.st_size;
}
}
}
closedir(dir);
return total_size;
}