gpt4 book ai didi

c - 如何检测 C 中的文件写入错误?

转载 作者:IT王子 更新时间:2023-10-29 01:10:17 26 4
gpt4 key购买 nike

我有一个嵌入式环境,用户可以在其中插入或移除 USB 闪存驱动器。我想知道驱动器是否已被移除,或者当我尝试写入驱动器时是否存在其他问题。然而,Linux 只是将信息保存在它的缓冲区中,并在没有指示错误的情况下返回。
我使用的计算机带有 2.4.26 内核和 libc 2.3.2。
我以这种方式安装驱动器:
i = mount(MEMORY_DEV_PATH, MEMORY_MNT_PATH, "vfat", MS_SYNCHRONOUS, NULL);
有效:
50:/root # mount<br/>
/dev/scsi/host0/bus0/target0/lun0/part1 on /mem type vfat (rw,sync)<br/>
50:/root #

稍后,我尝试向其中复制一个文件:

int ifile, ofile;
ifile = open("/tmp/tmpmidi.mid", O_RDONLY);
if (ifile < 0)
{
perror("open in");
break;
}
ofile = open(current_file_name.c_str(), O_WRONLY | O_SYNC);
if (ofile < 0)
{
perror("open out");
break;
}
#define BUFSZ 256
char buffer[BUFSZ];
while (1)
{
i = read(ifile, buffer, BUFSZ);
if (i < 0)
{
perror("read");
break;
}
j = write(ofile, buffer, i);
if (j < 0)
{
perror("write");
break;
}
if (i != j)
{
perror("Sizes wrong");
break;
}
if (i < BUFSZ)
{
printf("Copy is finished, I hope\n");
close(ifile);
close(ofile);
break;
}
}

如果这段代码是用写保护的USB存储器执行的,结果是

Copy is finished, I hope

在控制台上内核的一连串错误消息中。
我相信如果我只是移除 USB 驱动器(而不卸载它),也会发生同样的事情。
我也摆弄过devfs。我想出了如何让它自动安装驱动器,(通过 REGISTER 事件)但是当我拔出内存时它似乎永远不会触发 UNREGISTER。
如何在我的程序中确定我是否已成功创建文件?

7 月 4 日更新:没有检查 close() 的结果是我的愚蠢疏忽。不幸的是,该文件可以无误地关闭。所以这没有帮助。 fsync() 怎么样?这听起来是个好主意,但也没有发现错误。
如果我有这样的东西,/sys 中可能会有一些有趣的信息。我相信直到 2.6 才添加它。?。
关于我的闪存驱动器质量的评论可能是有道理的。是较早的作品之一。事实上,现在写保护开关似乎非常罕见。
我想我必须使用矫枉过正的选项:创建一个文件,卸载并重新安装驱动器,然后检查文件是否存在。如果那不能解决我的问题,那么事情就真的搞砸了! self 提醒:确保您尝试创建的文件不存在!
顺便说一下,这确实是一个 C++ 程序。您可以通过 .c_str() 来判断,为了简单起见,我打算将其编辑掉。

最佳答案

如果您的应用程序想要将一个或多个文件保存到 USB 内存棒,并让用户在小 LED 熄灭后立即拔出内存棒,您需要

  1. mount() 写入文件前的 U 盘

    你不需要为此挂载 SYNC,这有助于处理劣质 U 盘

  2. 使用正确的代码保存文件

    您对 C 低级 I/O 的尝试是非常不正确的。特别是,任何 read()write() 都可以返回一个 short count,即 1 和请求大小之间的任何正值,包括在内,但不表示任何类型的错误。

  3. fsync() U 盘上的文件

    验证它是否返回成功。如果是,那么您就知道数据已写入 USB 内存棒。

  4. fsync() U 盘上包含文件的目录

    验证它是否返回成功。如果是这样,那么您就知道文件元数据已写入 USB 内存棒,现在即使用户拔出 USB 内存棒也应该可以访问该文件。

  5. umount() U 盘

    这将一直阻塞,直到 USB 内存棒准备好断开连接,因此您的应用程序看起来应该正在保存到文件,直到 umount() 返回。

    如果您执行了上面的 fsync()umount() 应该非常直接。根据文件系统的不同,内核可能希望进行一些簿记,但无论如何都不会花费很长时间。

其他任何东西都是不可靠的。您或许可以通过安装具有同步访问权限的 VFAT 分区来做出某些假设,但这基本上只是徒劳。

如果您不想以 root 权限运行您的应用程序,您始终可以编写一个简单的特权服务来管理挂载和卸载。如果您怀疑在某个时候可能需要多个应用程序,我会非常热情地建议您这样做,因为只有集中式安装器/卸载器才能知道媒体何时准备就绪。 (如果另一个应用程序同时写入同一个 USB 媒体,它可能会延迟返回“未安装”消息。顺便说一句,当您不需要同步安装 USB 媒体时,这非常有效。)我个人会在 /var/run/ 中使用 unix 域数据报套接字,也许是 /var/run/mounter.socket,用于进程间通信。

最后,如果您的 Linux 内核配置正确并且您安装了 /sys/ 分区,您可以扫描所有 /sys/block/sd?/ 目录以查找可移动媒体:

  • /sys/block/sd?/removable 将包含一个非零的十进制数字字符串
  • /sys/block/sd?/size 包含以 512 字节为单位的设备大小,为十进制数字字符串
  • /sys/block/sd?/device/vendor 包含字符串形式的供应商名称
  • /sys/block/sd?/device/model 包含模型名称作为字符串

这些条目是硬件级的,只要 USB 内存棒连接并通电就可用;安装与否无关紧要。如果/当用户拔出 U 盘时,整个设备目录树将立即消失。

关于c - 如何检测 C 中的文件写入错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11322262/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com