1

When reading K&R, I became interested in how the file position is determined. By file position, I mean where in the file the stream is currently reading or writing. I think it must have something to do with the file pointer, or the piece of data it's pointing to. So I checked stack overflow, and find the following answer:

Does fread move the file pointer?

The answer indicates that file pointer will change with the change of file position. This makes me very confused, because in my understanding, a file pointer for a certain file should always point to the same address, where information about this file is stored. So I wrote a small piece of code, trying to find the answer:

#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);
}

It gives the output 1, which I believe indicates that the file pointer actually doesn't move and is still pointing to the same address. I have also changed the fread line to be a fseek, which gave the same output. So does file pointer move with the change of file position, or where am I wrong in the verifying process?

Thanks!

Community
  • 1
  • 1
Albert Zhou
  • 23
  • 1
  • 5
  • Nooo.... surely you understand that file systems require more than some pointer that moves to control access to a file! The FILE* 'file pointer' is typically the base address of a file control block - a whole struct of metadata about the file. – Martin James Aug 21 '15 at 14:50
  • you seem to be confusing the 'FILE * fp' that points (after a call to fopen()) to a 'file descriptor' control block to the data within the 'file descriptor' control block that indicates the current device, cylinder, track, sector, etc on the (in the general case) hard disk. – user3629249 Aug 22 '15 at 17:05

3 Answers3

5

I think you are confusing the general concept of pointers in C, vs. the nomenclature of a "file pointer". FILE is just a structure that contains most of the "housekeeping" attributes that the C stdio runtime library needs to interact with when using the stdio functions such as, fopen(), fread(), etc. Here is an example of the structure:

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;

Note that this may be somewhat platform-dependent, so don't take it as gospel. So when you call fopen(), the underlying library function interacts with the O/S's file system APIs and caches relevant information about the file, buffer allocation, etc, in this structure. The fopen() function allocates memory for this structure, and then returns the address of that memory back to the caller in the form of a C Pointer.

Assigning the pointers values to another pointer has no effect on the attributes inside the FILE structure. However, the FILE structure, internally, may have indexes or "pointers" to the underlying O/S file. Hence, the confusion in terminology. Hope that helps.

OldProgrammer
  • 12,050
  • 4
  • 24
  • 45
1

You are right fp is never changed by fread, fseekor other f... functions. Except, of course, if you do fp = fopen(...), but then you are assigning the return value of fopen to fp and then fp changes of course.

Remember, in C parameters are passed by value, so fread cannot change it's value.

But fread does change the internal structure fp points to.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • And it's not even guaranteed to change the structure: Some implementation could just piggyback on a lower-level file API using POSIX-style file descriptors, and simply put only the descriptor in the structure (though it would probably be slow performance-wise). – Medinoc Aug 21 '15 at 14:54
  • Thanks. The "pass by value" comment is really convincing. – Albert Zhou Aug 21 '15 at 15:12
1

You made some confusion between a file pointer, under common definition, and the pointer in the file. Normally with the term file pointer we refer to a pointer to a FILE structure. That structure contains all variables necessary to manage file access. This structure is created upon a successful opening of a file, and remains the same (same address) for all the time until you fclose() the file (when became undefined).

Inside the FILE structure there are many pointers that points to the file block on disk and to the position inside the current record. These pointers, managed by file I/O routines, changes when file is accessed (read or write). And these pointers are that to which the answer you cited refers.

Frankie_C
  • 4,764
  • 1
  • 13
  • 30
  • So you mean the file position is determined by a pointer inside the FILE structure? But how can this work if there is only a descriptor? I mean if a file is opened with system call open() rather than library routine open, there is no such thing as a FILE structure. Under this circumstance, file position should still be determined and can be changed by function like lseek. – Albert Zhou Aug 21 '15 at 15:10
  • @AlbertZhou File control structures are many. A first level is in the OS driver to take care of use of disk raw blocks, the next level is in the filesystem driver where raw data is organized in directories and files. Above that there is the so called low-level I/O (and `open()` is a low level) that has its own control structures. Then there is the High level I/O that uses FILE structures. `fopen()` uses FILE structure, that use a low level I/O that use filesystem that use raw I/O. Life is not easy ;-) – Frankie_C Aug 21 '15 at 15:24
  • @AlbertZhou I forget a file descriptor is an index to an array of file control structures used by low level I/O routines. So there is data there not only a 'descriptor'... – Frankie_C Aug 21 '15 at 15:28