Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Spontaneous file closing?

Status
Not open for further replies.

KempCGDR

Programmer
Jan 10, 2003
445
GB
I have a problem with an application I'm writing where files are spontaneously closed for no real reason. In one part, I have

AssignFile(FileS100, Filename);
Reset(FileS100);
For k := 0 to (FileSize(FileS100)-1) do
begin
Seek(FileS100, k);

The file is closed between the start of the loop and the seek (putting ShowMessage(IntToStr(FileSize(FileS100))) just before the loop gives the correct size).

In another place I have

Filename := 'Check.tmp';
AssignFile(TempFile, Filename);
Rewrite(TempFile);

{Loads of code (including loops and whatnot)}

CloseFile(TempFile);
If Not DeleteFile('Check.tmp') then ShowMessage('TempFile error');

It says file not open at the CloseFile. The only other CloseFile command in that section of code is for a file with a completely different variable name so I haven't typed it wrong and already closed it. Also, the file is read from, written to and seeked a lot in the code between the rewrite and the closefile and none give me any errors.

Any ideas?
 
Please post more of your code, especially the var section so we can see exactly what type of file you are using. (file? textfile? file of byte?)

It is difficult enough to try to diagnose a problem based on a fragment of code. It is almost impossible when essential information is withheld preventing us from being able to reproduce the symptoms in a test app.
 
sorry, kinda slipped my mind,

var
LastStat,LastSet,IdentMatch:Boolean;
i,j,k,l,NextID:Integer;
DefFile:TIniFile;
Filename:String;
FileS100:File of Str100Type;
VarS100:Str100Type;
TempFile:File of ShortString;
TempVar:ShortString;

Str100Type is as below:

Str100Type = Record
Card:Integer;
ValueNo:Integer;
Value:String[100];
end;
 
The file in the first case already exists, I have permissions to all the files/dirs (this is on my home comp: win98, no restrictions set up). No files are read-only.
 
I'll get everything eventually.

In the second piece, it says the file isn't open at the CloseFile, but if I comment that out then the DeleteFile fails, presumably because the file is open (it does exist at that point).
 
Ok, second one fixed, simple mistake on my part. The first one is still really annoying, it'll tell me the filesize before the start of the loop, but afterwards it says it's not open, since when did for..if statements close files?
 
Ok, second one fixed, simple mistake on my part. The first one is still really annoying, it'll tell me the filesize before the start of the loop, but afterwards it says it's not open, since when did 'for' statements close files?
 
I can't reproduce your results. What is the difference between my test bench and your app?

Type declaration:
Code:
type
   Str100Type = Record
      Card:Integer;
      ValueNo:Integer;
      Value:String[100];
   end;

Code to load a test file:
Code:
procedure TForm1.Button6Click(Sender: TObject);
var
   Filename:String;
   FileS100:File of Str100Type;
   FileS100Handle:integer;
   VarS100:Str100Type;
begin
  Filename := 'c:\text.txt';
  FileS100Handle := FileOpen(Filename, fmOpenWrite);
  VarS100.Card := 1;
  VarS100.ValueNo := 21;
  VarS100.Value := 'Data for record one';
  FileWrite(FileS100Handle,VarS100,SizeOf(Vars100));
  VarS100.Card := 2;
  VarS100.ValueNo := 22;
  VarS100.Value := 'Data for record two';
  FileWrite(FileS100Handle,VarS100,SizeOf(Vars100));
  VarS100.Card := 3;
  VarS100.ValueNo := 23;
  VarS100.Value := 'Data for record three';
  FileWrite(FileS100Handle,VarS100,SizeOf(Vars100));
  FileClose(FileS100Handle);
end;

Code to access the test file:
Code:
procedure TForm1.Button5Click(Sender: TObject);
var
   LastStat,LastSet,IdentMatch:Boolean;
   i,j,k,l,NextID:Integer;
   Filename:String;
   FileS100:File of Str100Type;
   VarS100:Str100Type;
   TempFile:File of ShortString;
   TempVar:ShortString;
begin
  Filename := 'c:\text.txt';
  AssignFile(FileS100, Filename);
   Reset(FileS100);
   For k := 0 to (FileSize(FileS100)-1) do
   begin
      Seek(FileS100, k);
   end;
end;
 
I can't see any difference, the stuff is written to the file differently to how I did it - write(FileVar, String), but the aqccessing code etc is the same. I've tried mine in two computers and both gave the error. Strange.
 
So.... did you run a test with my code? Did it fail the same way?

What does your file actually look like? Can you post the code you use to create it?

Are you running with "Stop on Delphi Exceptions" checked? (Tools/Debugger Options - Language Exceptions)

You've got me curious now.
 
I'll try to upload as much of the stuff as needed from the app (relevant source, datafiles etc) to my website and post a link so you can try the stuff out. At the mo I'm at college and I can't get access to Delphi, will have to be Saturday. Most of the settings will be as they are on install (Delphi 3 btw, seriously need to upgrade) but it's possible my 'optmizing' has changed something strange.
 
Ok, all the stuff you should need is at


Obviously Splash is the form (there's the pas, dfm and dcu files there). It uses KCommon.dll and the others are files it reads/writes. It should work with everything in the same directory.

On another note, half the code in that form is unneccessary for what we're trying to fix, but removing it removed the problem (pity it's needed for other stuff).
 
Correction, you have the modified version and the problem still exists in it.
 
If the program just sits there doing nothing when you run it, then it's working, I removed the code that moves to the next form. In reponse to your other question, Delphi Exceptions is on.
 
I looked at the code but I couldn't get very far without the definition for GSDef.

However, in looking at the .S100 files, I have to ask, have you tested the program with a small subset of carefully crafted test data? I get the impression that somehow you are encountering a file error which is not being handled in the normal way. It may be my imagination, but the file formats don't seem all that consistent.
 
Yeah, sorry, GSDef (among others) is a global that I'm so used to using I just forgot you don't have the definition. The file formats are how they should be and I know what's in the files, they should be ok. The global unit I use will be uploaded soon
 
I think I found the problem. If you look in Splash.pas you will find the following sequence of code:
Code:
   CloseFile(TempFile);
   If IdentMatch = False then
     begin
       Seek(TempFile, FileSize(TempFile));
       Write(TempFile, VarS100.Value);
     end
   else   ShowMessage('Datafile error in '+Filename+chr(13)+'Duplicate identifier');
You are getting the "103" error on the closed TempFile (Check.tmp)

I'm still curious how you are using the various .s100 files when they don't apppear to have the s100 format. But, what the hey, if it works for you...


 
This is just getting stupid, I have two versions of code for this thing on two computers and floppy I use to transfer it died. For me, the error happens on the Seek in that bit you posted, I'm going to get ANOTHER copy of the latest version of the code (I changed bits that I forgot about in this one).

Damn floppy disks never working and they think they're so good but they just can't cope with the slightest wrong use and the Allocation Table gets overwritten and the files vanish and then you just wanna crush it like the weak fool that it is...
 
Much as I hate posting code here, I have no FTP access til tomorrow, so here's the code to replace what was in Splash (from the comment that's in here onwards):

//Check data files for rule violations
For i := 1 to 5 do
begin
For j := 1 to 15 do
begin
If GSDef.StatSets.Stats[j].Ident = True then
begin
Filename := 'Check.tmp';
AssignFile(TempFile, Filename);
Rewrite(TempFile);

If (GSDef.StatSets.Stats[j].Len > 30) and (GSDef.StatSets.Stats[j].Len < 101) then
begin
Filename := Concat(Datadir,GSDef.StatSets.Name,'.s100');
If FileExists(Filename) then
begin
AssignFile(FileS100, Filename);
Reset(FileS100);
For k := 0 to (FileSize(FileS100)-1) do
begin
Seek(FileS100, k);
Read(FileS100, VarS100);
If VarS100.ValueNo = j then
begin
IdentMatch := False;
For l := 0 to FileSize(TempFile)-1 do
begin
Seek(TempFile, l);
Read(TempFile, TempVar);
If TempVar = VarS100.Value then IdentMatch := True;
end;
If IdentMatch = False then
begin
Seek(TempFile, FileSize(TempFile));
Write(TempFile, VarS100.Value);
end
else
begin
ShowMessage('Datafile error in '+Filename+chr(13)+'Duplicate identifier: '+VarS100.Value);
ErrorNo := 1;
end;
end;
end;
CloseFile(FileS100);
end;
end;
CloseFile(TempFile);
If Not DeleteFile('Check.tmp') then ShowMessage('TempFile error');
end;
end;
end;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top