eof() on files missing the ^Z terminator.

I have experienced this on some accasions lately, and I'm stumped as to how to fix it.

The company I work with produces some HR software. one feature of this SFW is the ability to import payroll files into the system. These are standard Text files with each line marked as to what it is. An example of this file would be:

[ORg name deleted for security]



Now when the system reads this file (which can and usually does contain multiple .BEGIN and .END lines, as well as sometimes having multiple .BEGINDEPOSTS, .BEGINORGANIZATION, .ENDDEPOSITS, and .ENDORGANIZATION lines), it loops through based on a readln and the EOF() call. Fine right? However, when a customer called stating that their import was locking up and there had been absolutly no code changes, I grabbed their file and examined it. Odd thing I noticed, NO ^Z AT THE END OF THE FILE! Here's a debug output of the bottom of the file:

0FA7:01A0  5A 41 54 49 4F 4E 0D 0A-0D 0A 0E 8B 87 2E 4B A3   ZATION........K.

Notice the conspicous lack of a 1A after the end of the ZATION? When using this file, the system locks up. On a whim, I used debug to reaplce the 0E with a 1A (end of file/Ctl-Z). Result: System behaves perfectly.

So my question is: Is there a way I can force delphi to recognise the end of a file? Obviously windows recognised it because if I pull the file into a program like EDIT.COM, it reads the expected portion and thats it. But if I make changes to the file and re-save it back, still no EOF mark. So Obviously Windows is using some other method to check for the end of a file. How can I replicate that behavior in my code?

Who is Participating?
Hi DanEgli,

may be you'd like to use TStringList instead of work with text file. It's easy to use, take a look at methods LoadFromFile, SaveToFile. TStringList also recognized end of file by it's physically end, but it doesn't hang up system if no EOF detected.

Why not use this function to know the size of the file and then read by blocks...... whith the file management routines?

function FileSeek(Handle, Offset, Origin: Integer): Integer; overload;
function FileSeek(Handle: Integer; const Offset: Int64; Origin: Integer): Int64; overload;


Use FileSeek to position the file pointer in a file that was opened with FileOpen or FileCreate. Handle contains the file handle that was returned by FileOpen or FileCreate.

Offset specifies the number of bytes from Origin where the file pointer should be positioned. Origin is a code with three possible values, denoting the beginning of the file, the end of the file, and the current position of the file pointer.

Origin     Action

0     The file pointer is positioned Offset bytes from the beginning of the file.
1     The file pointer is positioned Offset bytes from its current position.
2     The file pointer is positioned Offset bytes from the end of the file.

If FileSeek is successful, it returns the new position of the file pointer; otherwise, it returns -1.

Note:     Do not mix routines that take or return file handles with those that use Pascal file variables (typically seen as var F). To move the file pointer in a file specified by a Pascal file variable, use the Seek procedure instead.
DanEgliAuthor Commented:
marcoszorrilla/ITugay :

   We are trying to develop a fix that does not involve rewriting the entire routine from the ground up. If we use a String List or the FileSeek procedures, we would have to delete the entire fille IO logic and rewrite it from the ground up. That is a last resort I'm affraid.

DanEgliAuthor Commented:
We did not want to rewrite the whole routine, but it looks like it's the best option. And it's a good idea. Thanks!
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.