Solved

eof() on files missing the ^Z terminator.

Posted on 2002-05-26
4
238 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

743 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now