Solved

eof() on files missing the ^Z terminator.

Posted on 2002-05-26
4
243 Views
Last Modified: 2010-04-04
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:

.BEGINORGANIZATION
[ORg name deleted for security]
.BEGINDEPOSITS
.BEGIN

987654321

F
MED
1
0
0000005.00
0
05/07/2002
N
SB
.END
.ENDDEPOSITS
.ENDORGANIZATION


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?

Thanks!
0
Comment
Question by:DanEgli
  • 2
4 Comments
 
LVL 3

Expert Comment

by:marcoszorrilla
ID: 7036505
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;

Description

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.
0
 
LVL 9

Accepted Solution

by:
ITugay earned 90 total points
ID: 7036548
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.

------
Igor.
0
 
LVL 1

Author Comment

by:DanEgli
ID: 7037522
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.

0
 
LVL 1

Author Comment

by:DanEgli
ID: 7267510
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!
0

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Along with being a a promotional video for my three-day Annielytics Dashboard Seminor, this Micro Tutorial is an intro to Google Analytics API data.
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

776 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question