树莓派用C语言自动挂载USB及读取文件的路径问题求解
解决树莓派USB挂载与文件读取问题
问题分析
你遇到的核心问题出在挂载点逻辑与Linux自动挂载机制上:
- 用
/mnt/usb挂载失败:默认树莓派的/mnt目录下没有usb子目录,挂载命令要求目标目录必须存在才能执行。 - 挂载到
/media/user成功但找不到文件:/media/user是桌面环境自动挂载服务(udisks)的根目录,USB驱动器会被自动挂载到/media/user/[卷名]子目录中——你手动挂载到/media/user相当于覆盖了自动挂载的根目录,实际文件在自动生成的卷名子目录里,代码直接在/media/user下查找自然找不到。 - 直接用
/media/user/8.1 GB Volume当挂载点报错:这个目录是udisks自动创建的,手动挂载要求目标目录是预创建的空目录,且带空格的路径未转义会被shell解析为多个参数,导致"bad mount"错误。
解决方案
方案1:手动创建固定挂载点(推荐)
这是最稳定的方式,不受自动挂载服务干扰:
- 创建挂载目录并配置权限:
sudo mkdir -p /mnt/usb sudo chown user:user /mnt/usb # 将user替换为你的树莓派用户名
- 修改代码挂载点为
/mnt/usb,同时修复挂载检查逻辑(原函数用strstr会误判包含该路径的其他挂载点)。
方案2:适配自动挂载路径
若想利用udisks自动挂载,需动态获取卷名对应的挂载路径:
- 通过
blkid命令获取USB驱动器UUID,在/etc/fstab中配置自动挂载到固定路径;或在代码中解析/proc/mounts,找到/dev/sda1对应的实际挂载点。
修改后的代码
以下是修复挂载检查逻辑、适配固定挂载点的完整代码:
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> // 精确匹配挂载点,避免误判包含该路径的其他挂载项 bool isMounted(const char *mountPoint) { FILE *mountsFile = fopen("/proc/mounts", "r"); if (mountsFile == NULL) { perror("Failed to open /proc/mounts"); exit(EXIT_FAILURE); } char dev[64], mp[256], fs[64], opts[128]; while (fscanf(mountsFile, "%s %s %s %s", dev, mp, fs, opts) != EOF) { if (strcmp(mp, mountPoint) == 0) { fclose(mountsFile); return true; } } fclose(mountsFile); return false; } int main() { const char *mountPoint = "/mnt/usb"; // 固定挂载点 const char *usbDevice = "/dev/sda1"; const char *fileName = "example.txt"; // 挂载USB驱动器(未挂载时执行) if (!isMounted(mountPoint)) { char mountCommand[256]; // 根据USB文件系统调整-t参数:vfat/ntfs-3g/ext4,ext4可省略 snprintf(mountCommand, sizeof(mountCommand), "sudo mount -t vfat %s %s", usbDevice, mountPoint); int mountResult = system(mountCommand); if (mountResult != 0) { printf("Mount command failed with exit code %d\n", mountResult); return EXIT_FAILURE; } } // 确认挂载成功 if (!isMounted(mountPoint)) { printf("Failed to mount the USB drive.\n"); return EXIT_FAILURE; } // 拼接文件路径 char filePath[256]; snprintf(filePath, sizeof(filePath), "%s/%s", mountPoint, fileName); FILE *file = fopen(filePath, "r"); if (file == NULL) { perror("Failed to open the file"); // 输出具体错误原因(如文件不存在/权限不足) // 尝试卸载挂载点 char umountCommand[256]; snprintf(umountCommand, sizeof(umountCommand), "sudo umount %s", mountPoint); system(umountCommand); return EXIT_FAILURE; } // 读取并打印文件内容 char ch; while ((ch = fgetc(file)) != EOF) { printf("%c", ch); } printf("\n"); fclose(file); // 卸载USB驱动器 char umountCommand[256]; snprintf(umountCommand, sizeof(umountCommand), "sudo umount %s", mountPoint); int umountResult = system(umountCommand); if (umountResult != 0) { printf("Unmount command failed with exit code %d\n", umountResult); return EXIT_FAILURE; } return EXIT_SUCCESS; }
额外注意事项
- 若USB是NTFS格式,需先安装
ntfs-3g:sudo apt install ntfs-3g,并将代码中的-t vfat改为-t ntfs-3g。 - 避免运行程序时输入sudo密码:通过
sudo visudo添加一行user ALL=(ALL) NOPASSWD: /bin/mount, /bin/umount(替换user为你的用户名)。 - 确认USB设备节点:用
lsblk命令查看实际设备名(可能不是/dev/sda1)。
内容的提问来源于stack exchange,提问作者JRCastle
相关产品推荐
相关产品推荐

