#include
#include
#include
#include
#include
void search_file_in_dir(const char *dir_path, const char *file_name);
int main(int argc, char *argv[]) {
if (argc != 3) {
fprintf(stderr, "Usage: %s [dir] [file]\n", argv[0]);
return -1;
}
search_file_in_dir(argv[1], argv[2]);
return 0;
}
void search_file_in_dir(const char *dir_path, const char *file_name) {
DIR *dir = opendir(dir_path);
if (dir == NULL) {
perror("opendir");
return;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
char file_path[1024];
snprintf(file_path, sizeof(file_path), "%s/%s", dir_path, entry->d_name);
struct stat st;
if (stat(file_path, &st) == -1) {
perror("stat");
continue;
}
if (S_ISDIR(st.st_mode)) { // 如果是目录,则递归搜索
search_file_in_dir(file_path, file_name);
} else if (S_ISREG(st.st_mode)) { // 如果是普通文件,则判断文件名是否匹配
if (strcmp(entry->d_name, file_name) == 0) {
printf("%s/%s\n", dir_path, file_name);
}
}
}
closedir(dir);
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
void print_file_info(const char *path, const struct stat *file_stat)
{
// 文件类型和访问权限
printf("%c", S_ISDIR(file_stat->st_mode) ? 'd' : '-');
printf("%c", file_stat->st_mode & S_IRUSR ? 'r' : '-');
printf("%c", file_stat->st_mode & S_IWUSR ? 'w' : '-');
printf("%c", file_stat->st_mode & S_IXUSR ? 'x' : '-');
printf("%c", file_stat->st_mode & S_IRGRP ? 'r' : '-');
printf("%c", file_stat->st_mode & S_IWGRP ? 'w' : '-');
printf("%c", file_stat->st_mode & S_IXGRP ? 'x' : '-');
printf("%c", file_stat->st_mode & S_IROTH ? 'r' : '-');
printf("%c", file_stat->st_mode & S_IWOTH ? 'w' : '-');
printf("%c", file_stat->st_mode & S_IXOTH ? 'x' : '-');
// 硬链接数、所有者、组、大小
printf(" %2ld ", file_stat->st_nlink);
struct passwd *pw = getpwuid(file_stat->st_uid);
printf("%-8s ", pw ? pw->pw_name : "unknown");
struct group *gr = getgrgid(file_stat->st_gid);
printf("%-8s ", gr ? gr->gr_name : "unknown");
printf("%10ld ", file_stat->st_size);
// 时间
char time_buf[32];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M", localtime(&file_stat->st_mtime));
printf("%s ", time_buf);
// 文件名
printf("%s\n", path);
}
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "Usage: %s \n" , argv[0]);
return 1;
}
DIR *dir = opendir(argv[1]);
if (!dir) {
perror("opendir");
return 1;
}
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
char path[1024];
snprintf(path, sizeof(path), "%s/%s", argv[1], entry->d_name);
struct stat file_stat;
if (lstat(path, &file_stat) == -1) {
perror("lstat");
continue;
}
print_file_info(entry->d_name, &file_stat);
}
closedir(dir);
return 0;
}
#include
#include
int main() {
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
printf("Current working directory: %s\n", cwd);
} else {
perror("getcwd() error");
return 1;
}
if (chdir("/path/to/new/directory") == -1) {
perror("chdir() error");
return 1;
}
if (getcwd(cwd, sizeof(cwd)) != NULL) {
printf("New working directory: %s\n", cwd);
} else {
perror("getcwd() error");
return 1;
}
return 0;
}
#include
#include
#include
#include
#include
int main() {
// 创建一个名为 "example_directory" 的目录
if(mkdir("example_directory", 0777) == -1) {
perror("mkdir error");
exit(EXIT_FAILURE);
}
printf("Created directory successfully!\n");
// 删除刚才创建的目录
if(rmdir("example_directory") == -1) {
perror("rmdir error");
exit(EXIT_FAILURE);
}
printf("Deleted directory successfully!\n");
return EXIT_SUCCESS;
}
#include
#include
#include
#include
void print_tree(char *path, int depth) {
DIR *dir;
struct dirent *entry;
char new_path[1024];
if (!(dir = opendir(path))) {
perror("opendir error");
exit(EXIT_FAILURE);
}
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
printf("%*s%s/\n", depth*4, "", entry->d_name);
sprintf(new_path, "%s/%s", path, entry->d_name);
print_tree(new_path, depth+1);
} else {
printf("%*s%s\n", depth*4, "", entry->d_name);
}
}
closedir(dir);
}
int main(int argc, char *argv[]) {
char *path;
if (argc < 2) {
path = ".";
} else {
path = argv[1];
}
print_tree(path, 0);
return 0;
}
在磁盘上建立一个文件,然后把文件内容映射到虚拟内存上,在每个进程的虚拟存储器里面,单独开辟一个空间来进行映射。在多进程情况下,不会对实际的物理存储器(主存)消耗太大。
即将一个文件或者其它对象映射到进程的虚拟地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一 一对映关系。
实现这样的映射关系后,进程就可以采用指针的方式操作这一段内存,而系统会自动回写到对应的文件磁盘上,即完成了对文件的操作而不必再调用read,write等系统调用函数。相反,内核空间对这段区域的修改也直接反映用户空间,从而可以实现不同进程间的文件共享,也就是不再局限于具有亲缘关系的进程间通信。
简而言之,就是在进程虚拟空间上添加一个段,并将其与物理磁盘地址相连(映射),而在创建虚拟段的时候,并没有将任何文件数据拷贝至物理内存。
多个进程的地址空间都映射到同一块物理内存,这样多个进程都能看到这块物理内存,实现进程间通信,而且不需要数据的拷贝,所以速度最快。当系统断电后,其中的文件会全部自行销毁,这点与mmap不同。
对比:
1、mmap是在磁盘上建立一个文件,每个进程地址空间中开辟出一块空间进行映射。而对于shm而言,shm每个进程最终会映射到同一块物理内存。shm保存在物理内存,这样读写的速度要比磁盘要快,但是存储量不是特别大。
2、mmap:磁盘->进程,shm:进程->内存(断电清除)。共享内存shm是在内存中创建空间,然后每个进程映射到此处;内存映射mmap是在磁盘中创建一个文件,然后每个进程映射到此处;
3 当机器重启时,mmap把文件保存在磁盘上,所以不会丢失,而共享内存shm存储在内存上就会丢失;