Hi All,
I would like to some questions on fopen() / fread() of CCS.
I have noticed that when the "mode" parameter in fopen() is set to "r" reading and without an additional "t" (text) or "b" (binary) to specify the whether in text or binary mode, which then by C standard defaults "t"(text), fread() read at most the content of a file to the first '1A' (in hex) byte.
extern _CODE_ACCESS FILE *fopen(const char *_fname, const char *_mode);
extern _CODE_ACCESS size_t fread(void *_ptr, size_t _size, size_t _count, FILE *_fp);
FILE *fp;
int data_array[10000];
int f_size;
fp=fopen("data","r");
f_size=fread(&data_array[0],4,10000,fp); //four bytes per item, 10000 items
fclose(fp);
The file "data" could be of 1MB in size, but the return value of fread(), which is assigned to f_size, is only a small value (say, 300) and it can be confirmed to be true by comparing data_array[ ] contents with the original file "data".
Because of the lack of documentation with fopen()/fread(), I turned to the Visual C+ MSDN and found that:
1. "t" (text) is the default mode for fopen()
2. In "t" mode CTRL + Z (^Z, ASCII 1A) is treated as the end of the file.
3. In "b" (binary mode) there is no such treatment.
Also, in text mode, carriage return–linefeed combinations are translated into single linefeeds on input, and linefeed characters are translated to carriage return–linefeed combinations on output. When a Unicode stream-I/O function operates in text mode (the default), the source or destination stream is assumed to be a sequence of multibyte characters. Therefore, the Unicode stream-input functions convert multibyte characters to wide characters (as if by a call to the mbtowc function). For the same reason, the Unicode stream-output functions convert wide characters to multibyte characters (as if by a call to the wctomb function).
I thought on why in "t" mode there needs to be a number '1A' denoting the end of the file. Why is that necessary? Why cannot fread() directly query the OS (Windows, etc.) for the size of file and simply take the returned value on faith? Because in our everyday use, if one wants to know the size of a file on the disk, say a .avi movie, he can simply right click the file name and then choose "property", and Windows will the user its size instantly. Why wouldn't fread() just ask for the same?
Is this behavior (seeking file end in "t" mode) created because the designer of fopen() do not "trust" the OS? When a file is initially created locally or copied from other place, the OS should be able to know its size precisely and probably would log it in its file system's record. Is it possible someone to modify the file without using OS's file accessing routine? For example, a file whose original size is 100KB has been modified in size by other means other than the OS routine (magnetic, optical, etc.), and its last 33KB has been moved to the front and overwrite the original content, and the OS was completely unaware of this change, then obvious in this case the logged value of the file size no longer matches its latest condition.
Chances like this is rare in everyday use, but is still possible. Therefore, is it the intent of fopen()/fread()'s designer to let fopen() check the file size itself rather than getting this information from the OS?
And what about accessing one OS's disk file from another incompatible OS? In this case there is no way to ask for the file size directly and and any file accessing function (similar to fopen()/fread() but in the new OS, probably not using C language) needs to check the file size itself.
I have found that there could be so many different reasons and concerns for why C's fopen()/fread() needs to check for the file end itself. I could not determine which of them was the real intent of the designer.
Could anyone drop a few words on this?
Sincerely,
Zheng