You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 20:15:03