C: Reading past EOF.
Hi: I open a file this way:
Code:
Code:
unsigned char chk; |
You should always check the return value of fread() to determine if an error (possibly indicating EOF) was detected.
Every time a file is opened, the file pointer is referencing the beginning of the file. You can move the file pointer, without the need of reading the file, using fseek(). You will of course have to know ahead of time the byte offset into the file that you want to go to. In a previous project I worked on, I stored the next read position within 8 bytes at the beginning of the file. Thus I read the position first, then performed an fseek() afterwards. P.S. I am confused with the declaration of an unsigned char (chk), and then the usage of _chk (type unknown) in which you access it as if it were an array. But suffice to say, it appears that you are reading one character at a time, not 16-bits (or unsigned short). |
Yes, I am. And thanks for your concepts. Now, to strip the program off of these mistakes is what I intend to do. But first, I would like to know what the effect is of reading the file internal buffer past end of the file. Could you tell me?
EDIT: having a problem with X. I'll resume later. |
The standard for fread explicitly does not tell you what will be in your buffer after an fread that fails due to eof (or for any other reason).
|
I think this: to simplify, assume logical sectors on the drive are 8192 bytes long. When I read for the first time (in the program above) all 8192 bytes will be in some buffer. If EOF is at offset 7999 in this buffer, there will be 192 spurious chars in the buffer. If I read them now, they will be the same as if I close the file, open it again and repeat same operation, because those bytes come from the fixed disk sector, where they can't change.
|
Quote:
|
The program is working, though not all as I'd like. As it writes my flash device, I must be careful with it. Therefor, before changing the program, I must fully realize its workings. OK.
Could we be a bit more ... to the hardware view of the thing. Operations involving hardware, most times read entire blocks. So be sure an fread execution accesess the disk or controller buffer, only if it needs a new cluster (block) or several of them. In the buffer nearer the user, there will also be 8192 chars. Only that the user (program) will notice an error condition if he attemps to read past EOF. I think it's as simple as that. |
Quote:
Quote:
I would expect the user buffer to be unmodified by the failing fread. Since you used the same buffer for a successful fread earlier, I would expect the contents from the last successful fread to remain in the buffer through the subsequent unsuccessful freads. But I would not rely on that, because the standard for fread says you cannot rely on the user buffer contents from an unsuccessful fread. Quote:
The Linux kernel has buffers in its own memory space, that (among other uses) are used in situations where the end of a file does not land on a sufficiently aligned boundary. A physical read (from disk) into that kernel buffer will extend past the end of file, but the user requested read will be a memory to memory copy from the kernel buffer into the user buffer and that read will stop at the logical end of file. fread itself is a function executing in user mode. It has no ability to access the kernel buffer. It can make a request to the kernel to copy directly from the file (kernel buffer) into the final user buffer. Alternately, it can request the kernel to copy from the file to fread's own buffer, then fread can copy from its own buffer to the final user buffer. Either way, the kernel operation copying from the kernel buffer will stop at the end of file. |
Your answer's been very to the point, I mean helpful, though it leaves me at indetermination. I had already, before, made up my mind to rewrite the program to see if the indetermination in it goes away. But I have several sources of indertermiantion. To be honest, I have now one less, as I know THERE CAN BE indetermination. Thanks a lot.
|
All times are GMT -5. The time now is 01:08 PM. |