所以基本上,您真正想要的是获得一个文件描述符,并重新打开相同的文件,以获取单独的位置、共享、模式等。而且您想在Windows上执行此操作(其中“文件描述符”基本上是一个外部对象,不是直接由操作系统或运行时库使用的东西)。
令人惊讶的是,至少在MS VC++中有一种方法可以做到这一点。除了两个步骤之外,所有步骤都仅使用Win32 API,因此将其移植到其他编译器/库应该相当合理(我认为大多数都提供了这两个函数的版本)。这些函数用于将类Unix文件描述符转换为本机Win32文件句柄,并将本机Win32文件句柄转换回类Unix文件描述符。
1. 使用_get_osfhandle()将文件描述符转换为本机文件句柄
2. 使用GetFileInformationByHandleEx(FILE_NAME_INFO)获取文件的名称
3. 使用CreateFile打开该文件的新句柄
4. 使用_open_osfhandle()为该句柄创建文件描述符
我们现在拥有一个新的文件描述符,它指向相同的文件,但具有自己的权限、位置等。
在你的问题末尾,你似乎也想要"权限",但这看起来没有什么实际意义——权限附加到文件本身,而不附加到文件的打开方式,因此打开或重新打开文件对文件的权限没有影响。如果你真的想知道,可以使用GetFileInformationByHandle来获取,但是请注意,Windows中的文件权限与Unix中的(传统)文件权限相差很大。Unix对所有文件都有拥有者/组/世界权限,大多数系统也具有ACL(虽然它们工作的方式有所不同)。Windows要么根本没有权限(例如,FAT或FAT32上的文件),要么使用ACL(例如,在NTFS上的文件),但没有真正相当于Unix上大多数人习惯的传统拥有者/组/世界权限的东西。
也许你使用"权限"指的是文件是用于读取、写入还是两者兼备。获取它比之前提到的任何内容都要麻烦得多。问题在于它的大部分在库中,而不是Win32中,因此可能没有办法做到在编译器之间移植。在MS VC++ 9.0 SP1中(不能保证适用于
任何其他编译器),你可以这样做:
#include <stdio.h>
int get_perms(int fd) {
int i;
FILE * base = __iob_func();
for (i=0; i<_IOB_ENTRIES; i++)
if (base[i]._file == fd)
return base[i]._flag;
return 0;
}
由于这涉及到一些探险,我写了一个快速测试来验证它是否真正起作用:
#ifdef TEST
#include <io.h>
void show_perms(int perms, char const *caption) {
printf("File opened for %s\n", caption);
printf("Read permission = %d\n", (perms & _IOREAD)!=0);
printf("Write permission = %d\n", (perms & _IOWRT)!=0);
}
int main(int argc, char **argv) {
FILE *file1, *file2;
int perms1, perms2;
file1=fopen(argv[1], "w");
perms1 = get_perms(_fileno(file1));
fclose(file1);
file2=fopen(argv[1], "r");
perms2 = get_perms(_fileno(file2));
fclose(file2);
show_perms(perms1, "writing");
show_perms(perms2, "reading");
return 0;
}
#endif
结果似乎表明成功:
File opened for writing
Read permission = 0
Write permission = 1
File opened for reading
Read permission = 1
Write permission = 0
您可以将返回的标志与stdio.h中定义的_IOREAD、_IOWRT和_IORW进行测试。尽管我之前有所警告,但我应该指出,我认为(虽然我当然不能保证)库的这个部分相当稳定,因此真正的重大更改可能非常小。
然而,在另一个方向上,它基本上不可能与任何其他库一起使用。它可能会(但肯定不保证)与使用MS库的其他编译器配合使用,例如Intel、MinGW或Comeau使用MS VC++作为其后端。其中,我认为最有可能起作用的是Comeau,最不可能起作用的是MinGW(但这只是猜测;很可能它无法与它们中的任何一个一起使用)。
- 需要可再发行的Win32 FileID API Library。
HANDLE
仍在指向该路径时,可以安全地获取与句柄相关联的文件名,因为它不会改变。 - Matt Joiner