在C语言中重复使用fopen打开文件

3

我有一个关于"fopen"函数的问题。

FILE *pFile1, *pFile2;
pFile1 = fopen(fileName,"rb+");
pFile2 = fopen(fileName,"rb+");

我可以说pFile1 == pFile2吗?另外,FILE类型可以作为map的键吗?

谢谢!


3
pFilepFile2不会是相同的。请尝试一下。 - Ed Heal
还有为什么在C++中要使用stdio。当然,如果你喜欢,你可以将其用作密钥。毕竟,它只是一系列位,但你想证明什么呢? - Ed Heal
不,这两个指针不会相同,而且您也不希望出现这种行为。在这个例子中,FILE* 不仅仅是指向命名流的指针...每个指针都有自己的状态,比如当前位置。 - Andon M. Coleman
2个回答

5

我可以说 pFile1 == pFile2 吗?

不行。pFile1pFile2 是指向两个不同的 FILE 结构体的指针,分别由两个不同的函数调用返回。

试试看吧!

另外需要注意:

打开已经打开的文件的行为是有实现定义的。根据 C 标准:

FIO31-C. Do not open a file that is already open

第 7.21.3 小节,第 8 段 [ISO/IEC 9899:2011]:

打开附加(非临时)文件的函数需要一个字符串类型的文件名。组成有效文件名的规则是实现定义的。同时打开同一文件的行为也是实现定义的。

一些平台可能禁止同时打开同一个文件,但其他平台允许。因此,可移植代码不能依赖于违反此规则会发生什么。尽管在符合POSIX标准的系统上这不是问题。许多应用程序多次打开文件以进行并发读取(当然,如果您还需要写入操作,则可能需要并发控制机制,但那是另一回事)。

答案有任何错误吗? - Grijesh Chauhan

3

我可以说pFile1 == pFile2吗?

(在阅读Grijesh Chauhan的相关评论后进行了编辑)

你不能说pFile1 == pFile2,因为有两种情况:

  1. 系统禁止打开文件两次,在这种情况下,pFile2将为空
  2. 系统允许第二次打开,此时pFile2将指向不同的上下文。

顺便说一下,这是检查系统调用的成千上万个原因之一。

假设第二个调用成功,您可以使用pFile1搜索给定位置,同时使用pFile2从另一个位置读取。

顺便说一下,由于最终会访问相同的物理磁盘,所以做这件事很少是一个好主意,除非您确切地知道自己在做什么。在两个大文件的不同部分之间来回快速搜索可能会迫使磁盘驱动器在磁盘的两个物理部分之间摇晃,从而极大地降低I/O性能(除非磁盘是像SSD这样不需要寻道的设备)。

FILE类型可以用作映射的键吗?

不行,因为

  1. 使用一个未知大小的未知结构体作为键毫无意义,并且您对其生命周期没有直接控制。
  2. FILE类没有实现必要的比较运算符。

但是,您可以使用FILE *,因为任何指针都可以用作映射键。

然而,这样做非常危险。首先,指针对您来说就像随机数一样。它来自stdio库中的某个内存分配,并且您无法控制它。

其次,如果由于某种原因您释放了文件句柄(即关闭了文件),则除非您还从映射中删除文件,否则将继续使用无效的指针引用作为键。这样做可能是可行的,但在我看来既麻烦又危险。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接