【问题标题】:Will file pointer move with the change of file position?文件指针会随着文件位置的变化而移动吗?
【发布时间】:2015-08-21 14:43:22
【问题描述】:

在阅读 K&R 时,我对如何确定文件位置产生了兴趣。通过文件位置,我的意思是流当前在文件中读取或写入的位置。我认为它必须与文件指针或它指向的数据有关。于是我检查了堆栈溢出,找到了如下答案:

Does fread move the file pointer?

答案表明文件指针会随着文件位置的变化而变化。这让我很困惑,因为在我的理解中,某个文件的文件指针应该总是指向同一个地址,这个地址存储了这个文件的信息。于是我写了一小段代码,试图找到答案:

#include<stdio.h>
int main(void)
{
    char s[1000];
    FILE *fp,*fp1,*fp2;
    fp = fopen("input","r");
    fp1 = fp; /* File poiter before fread */
    fread(s,sizeof(char),100,fp);
    fp2 = fp; /* File pointer after fread */
    printf("%d\n",(fp1 == fp2) ? 1 : -1);
}

它给出了输出 1,我相信这表明文件指针实际上没有移动并且仍然指向相同的地址。我还将 fread 行更改为 fseek,它给出了相同的输出。那么文件指针是否会随着文件位置的变化而移动,或者我在验证过程中哪里出错了?

谢谢!

【问题讨论】:

  • Nooo.... 你肯定明白文件系统需要的不仅仅是一些移动的指针来控制对文件的访问! FILE*“文件指针”通常是文件控制块的基地址——关于文件的完整元数据结构。
  • 您似乎混淆了指向“文件描述符”控制块的“文件 * fp”(在调用 fopen() 之后)指向“文件描述符”控制块中的数据表示(一般情况下)硬盘上的当前设备、柱面、磁道、扇区等。

标签: c file pointers


【解决方案1】:

我认为您混淆了 C 中指针的一般概念与“文件指针”的命名法。 FILE 只是一个结构,其中包含 C stdio 运行时库在使用 fopen()、fread() 等 stdio 函数时需要与之交互的大部分“管家”属性。以下是该结构的示例:

typedef struct {
char *fpos; /* Current position of file pointer (absolute address) */
void *base; /* Pointer to the base of the file */
unsigned short handle; /* File handle */
short flags; /* Flags (see FileFlags) */
short unget; /* 1-byte buffer for ungetc (b15=1 if non-empty) */
unsigned long alloc; /* Number of currently allocated bytes for the file */
unsigned short buffincrement; /* Number of bytes allocated at once */
} FILE;

请注意,这可能有点依赖于平台,所以不要把它当作福音。所以当你调用 fopen() 时,底层库函数与操作系统的文件系统 API 交互,并在这个结构中缓存有关文件、缓冲区分配等的相关信息。 fopen() 函数为此结构分配内存,然后将该内存的地址以 C 指针的形式返回给调用者。

将指针值分配给另一个指针对 FILE 结构内的属性没有影响。但是,FILE 结构在内部可能具有指向底层 O/S 文件的索引或“指针”。因此,术语混乱。希望对您有所帮助。

【讨论】:

  • 非常感谢!我还认为这可能只是术语的问题。你的答案很清楚。
【解决方案2】:

你是对的 fp 永远不会被 freadfseek 或其他 f... 函数改变。当然,除非您使用fp = fopen(...),但是您将fopen 的返回值分配给fp,然后fp 当然会发生变化。

记住,在 C 中参数是按值传递的,所以fread 不能改变它的值。

但是fread确实改变了fp指向的内部结构。

【讨论】:

  • 而且它甚至不能保证改变结构:一些实现可能只是使用 POSIX 样式的文件描述符搭载在较低级别的文件 API 上,并且只需将描述符放在结构中(尽管它会可能在性能方面很慢)。
  • 谢谢。 “价值传递”的评论真的很有说服力。
【解决方案3】:

您在通用定义下的文件指针文件中的指针之间产生了一些混淆。 通常使用术语 file pointer 我们指的是指向 FILE 结构的指针。该结构包含管理文件访问所需的所有变量。此结构在成功打开文件时创建,并且一直保持不变(相同的地址),直到您fclose() 文件(当变得未定义时)。

在 FILE 结构中,有许多指针指向磁盘上的文件块和当前记录中的位置。这些指针由文件 I/O 例程管理,在文件被访问(读取或写入)时发生变化。 这些指针就是您引用的答案所指的。

【讨论】:

  • 所以你的意思是文件位置是由文件结构内的指针确定的?但是如果只有一个描述符,这怎么能工作呢?我的意思是,如果使用系统调用 open() 打开文件而不是打开库例程,则不存在 FILE 结构之类的东西。这种情况下,文件位置还是要确定的,可以通过lseek之类的函数来改变。
  • @AlbertZhou 文件控制结构很多。第一层是在操作系统驱动程序中处理磁盘原始块的使用,下一层是在文件系统驱动程序中,其中原始数据被组织在目录和文件中。除此之外还有所谓的低级 I/O(open() 是低级),它有自己的控制结构。然后是使用 FILE 结构的高级 I/O。 fopen() 使用 FILE 结构,它使用使用原始 I/O 的文件系统的低级 I/O。生活不容易;-)
  • @AlbertZhou 我忘记了文件描述符是低级 I/O 例程使用的文件控制结构数组的索引。所以那里的数据不仅仅是一个“描述符”......
猜你喜欢
  • 2012-05-28
  • 1970-01-01
  • 2021-11-28
  • 2014-06-25
  • 2018-03-14
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 2018-09-15
相关资源
最近更新 更多