使用自己的文件偏移量来复制文件描述符

如何从现有的文件描述符创build一个新的文件描述符,使得新的描述符在文件表中不共享相同的内部文件结构/条目? 具体的属性,如文件偏移量(最好是权限,共享和模式)不应该在新旧文件描述符之间共享。

Windows和Linux下, dup()将复制文件描述符,但是这两个描述符仍然指向进程文件表中相同的文件结构。 任何寻找任何描述符都会调整其他描述符的位置。

注意

我从那以后就收到了Windows和Linux的答案,并且经常调整这个问题,这让人们很难回答。 我会调整我的选票,并接受涵盖Windows Linux的最干净的答案。 向所有人道歉,我还是新来的SO范式。 感谢您的好评!

Solutions Collecting From Web of "使用自己的文件偏移量来复制文件描述符"

所以基本上,你真正想要的是给一个文件描述符,并基本上打开同一个文件再次,以获得一个单独的位置,共享,模式等,而你想在Windows上做这个(“文件描述符“基本上是一个外来对象,而不是由操作系统运行库直接使用的东西。

令人惊讶的是,有一种方法可以做到这一点,至少在MS VC ++。 除了两步之外,它只使用Win32 API,因此移植到其他编译器/库应该是相当合理的(我认为这两个函数的版本最多)。 这些是用于将Unix风格的文件描述符转换为本地Win32文件句柄,并将本机Win32文件句柄转换回Unix风格的文件描述符。

  1. 使用_get_osfhandle()将文件描述符转换为本机文件句柄
  2. 使用GetFileInformationByHandleEx(FILE_NAME_INFO) 1获取文件的名称
  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; // we've found our file return 0; // file wasn't found. } 

由于这涉及一些spelunking,我写了一个快速测试,以确认它可能实际上工作:

 #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库的其他编译器一起工作,例如使用MS VC ++的Intel,MinGW或Comeau作为其后端。 其中,我认为最有可能工作的将是Comeau,而最不可能的MinGW(但这只是一个猜测,这是一个很好的机会,不会与任何人工作)。

  1. 需要可再发行的Win32 FileID API库

所以,我建议读一下这个。 dup()和相关函数用于在文件描述符表中创建一个重复的值,指向打开文件表中的相同条目。 这是为了有相同的偏移量。 如果你open() ,你会创建一个新的条目打开文件表。

创建文件描述符的副本并且新的文件描述符在打开的文件表中具有不同的偏移量是没有意义的(这似乎与“重复”的意思相矛盾)。

我不确定你的问题实际上是什么。 我的意思是,这不是一个重复的东西。 你可以阅读:

/proc/self/fd/[descriptor]

并获取用于打开该文件描述符的字符串; 牢记这可能会提供一些陷阱,其中一些你实际上在你再次调用open()观察中注意到的。

也许你可以解释一点,我可以尝试更新来帮助。

为什么不在Windows上使用open()或CreateFile()再次打开文件? 这给你所有的自由不同的访问权限和单独的抵消。

这当然有缺点,你不能独占打开文件,但它很容易解决你的问题。