Linux下C语言获取可移动介质列表解决USB文件拷贝硬编码问题
解决方案
要实现跨用户、跨Windows USB设备的适配,你需要移除用户名、介质UUID、Windows用户名三处硬编码,按以下逻辑改造:
核心改造点
- 动态获取当前运行用户的信息,避免硬编码用户名和home路径
- 扫描系统挂载表过滤出Windows文件系统的可移动介质挂载点
- 自动匹配Windows介质下的Users目录内的Documents路径
完整改造后代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <pwd.h> #include <unistd.h> #include <linux/limits.h> // 检查路径是否为Windows格式可移动介质的Documents目录 int check_windows_doc_path(const char *mount_point, char *out_doc_path, size_t out_len) { char users_path[PATH_MAX]; snprintf(users_path, sizeof(users_path), "%s/Users", mount_point); DIR *users_dir = opendir(users_path); if (!users_dir) return 0; struct dirent *user_entry; while ((user_entry = readdir(users_dir))) { if (user_entry->d_type != DT_DIR || !strcmp(user_entry->d_name, ".") || !strcmp(user_entry->d_name, "..")) { continue; } char doc_path[PATH_MAX]; snprintf(doc_path, sizeof(doc_path), "%s/%s/Documents", users_path, user_entry->d_name); DIR *doc_dir = opendir(doc_path); if (doc_dir) { closedir(doc_dir); strncpy(out_doc_path, doc_path, out_len); closedir(users_dir); return 1; } } closedir(users_dir); return 0; } int main() { // 获取当前用户信息 struct passwd *pw = getpwuid(getuid()); if (!pw) { perror("无法获取当前用户信息"); return 1; } // 拼接源Documents路径和介质挂载根路径 char src_doc_path[PATH_MAX]; snprintf(src_doc_path, sizeof(src_doc_path), "%s/Documents", pw->pw_dir); char media_root[PATH_MAX]; snprintf(media_root, sizeof(media_root), "/media/%s", pw->pw_name); // 读取/proc/mounts过滤符合要求的挂载点 FILE *mounts = fopen("/proc/mounts", "r"); if (!mounts) { perror("无法读取系统挂载表"); return 1; } char dev[256], mount_point[PATH_MAX], fs_type[256]; while (fscanf(mounts, "%s %s %s %*s %*d %*d\n", dev, mount_point, fs_type) == 3) { // 过滤挂载点在/media/当前用户下,且为Windows常用文件系统的介质 if (strstr(mount_point, media_root) != mount_point) continue; if (strcmp(fs_type, "vfat") && strcmp(fs_type, "ntfs") && strcmp(fs_type, "ntfs3")) continue; // 查找该介质下的Documents目录 char target_doc_path[PATH_MAX]; if (check_windows_doc_path(mount_point, target_doc_path, sizeof(target_doc_path))) { // 拷贝源Documents下的所有普通文件到目标路径(保留你原有创建空文件的逻辑,需要写入数据可后续补充) DIR *src_dir = opendir(src_doc_path); if (!src_dir) { perror("无法读取源Documents目录"); continue; } struct dirent *entry; while ((entry = readdir(src_dir))) { if (entry->d_type != DT_REG) continue; char new_file_path[PATH_MAX]; snprintf(new_file_path, sizeof(new_file_path), "%s/%s", target_doc_path, entry->d_name); FILE *clone = fopen(new_file_path, "w"); if (clone) fclose(clone); } closedir(src_dir); } } fclose(mounts); return 0; }
注意事项
- 代码默认会将文件写入所有识别到的Windows USB设备的Documents目录,若需要指定唯一设备,可增加设备名匹配、用户选择的逻辑
- 用
PATH_MAX定义路径缓冲区,避免路径过长导致截断 - 如果需要严格过滤仅USB设备,可额外读取
/sys/block/[设备名去掉末尾数字]/removable文件判断是否为可移动设备,值为1就是可移动USB设备
内容的提问来源于stack exchange,提问作者person the human
相关产品推荐
相关产品推荐

