【发布时间】:2010-11-06 02:57:07
【问题描述】:
我知道,C++ 中有 is_open() 函数,但我希望一个程序检查一个文件是否未被另一个应用程序打开。有没有办法使用标准库来做到这一点?
编辑 - 在答案中澄清这是针对 Linux 应用程序的。
【问题讨论】:
我知道,C++ 中有 is_open() 函数,但我希望一个程序检查一个文件是否未被另一个应用程序打开。有没有办法使用标准库来做到这一点?
编辑 - 在答案中澄清这是针对 Linux 应用程序的。
【问题讨论】:
不仅标准库不具备这种功能,甚至一般情况下也不可能。您可以(在 linux 上)检查 /proc/*/fd — 但您的程序可能没有权限在其他用户的进程上执行此操作(例如,这是 Ubuntu 中的默认设置)。
【讨论】:
不,标准库没有这样的功能。
【讨论】:
如果您控制另一个进程(有源代码),最好的计划是在两个进程中都使用咨询锁。这种锁定是在 POSIX 中定义的,并且可以跨操作系统移植。
在 Linux 中,您可以使用实用程序 lsof 查看其他进程打开了哪些文件。
这仅限于您拥有的权限 - 您必须以特权用户的身份进行检查,否则您只会获得与执行检查的用户相同的用户打开的文件的结果。
我只知道命令行实用程序,不知道任何可以直接从 C 代码中使用的系统调用。
在 Linux 中,还可以为给定的文件系统打开 mandatory locking(mount -o mand),并在文件上设置特殊标志(chmod g-x,g+s)。然后,当您的进程尝试获取写锁时,如果另一个进程打开了文件,它将失败。这几乎从未使用过,但如果您完全控制有问题的系统,它可能是一种选择。
【讨论】:
以下代码可能有效。
int main(int argc, char ** argv)
{
int fd = open(argv[1], O_RDONLY);
if (fd < 0) {
perror("open");
return 1;
}
if (fcntl(fd, F_SETLEASE, F_WRLCK) && EAGAIN == errno) {
puts("file has been opened");
}
else {
fcntl(fd, F_SETLEASE, F_UNLCK);
puts("file has not been opened");
}
close(fd);
return 0;
}
【讨论】:
ls -al /proc/21862/fd/47 l-wx------ 1 user user 64 1월 29 17:12 /proc/21862/fd/47 -> /home/user/data/201802201020.mp4。 (Ubuntu)
也许你可以尝试获得一个完整的写锁?如果其他人将其打开以供阅读或写作,它将失败。
fopen("myfile.txt", "r+")
如果不是跨平台的,是Win32的,那么你可以请求更细粒度的锁。
见here
并查看dwShareMode,值为0,以及其他参数。
【讨论】:
不。除非其他应用程序使用咨询锁。
【讨论】:
如果不是本地人,您可以拨打Sysinternals' handle.exe 作为最后的手段...
【讨论】:
正如@Neil Butterworth 所说,标准库没有。
在 unix 中,您可以使用 fcntl 来使用文件锁。
您可以为您的 open 函数编写一个包装器,如果文件未被其他人打开,它会检查文件是否存在锁(如果不存在则锁)。您还应该为关闭编写一个包装器,以释放文件关闭时的锁定。
【讨论】:
在 Windows 中,这个 肮脏 的小技巧会起作用(如果文件存在并且您拥有正确的权限)
if ( 0 != rename("c:/foo.txt", "c:/foo.txt") ) {
printf("already opened\n");
}
它可能也适用于 Linux。
【讨论】: