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?
 
My problem has vanished, just like that, I changed some code in a completely different place (after it in fact) and it just went. Damn Delphi.

Anyway, Zathras, thanks for the help, sorry about that. If you can figure out what was wrong with it before, I'd be very interested.

btw, what's wrong with my file formats? You've got me worried now.
 
If I understand the structure of Str100Type correctly, it should be defining a record length of 109 bytes (4 for each integer and 101 for the string). When I look at any of the three sample files in your .zip file it looks like the record length is 112. Each string appears to have three null bytes appended to it. When I change the definition for the string to [103] it seems to work ok. When I leave the constant 100 in the code when creating the file, I can reproduce your file structure exactly.

Here is the quick and dirty code I used for testing:
Code:
unit S100;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  Str100Type = Record
     Card: integer;
     ValueNo: integer;
     Value: string
Code:
[103]
Code:
;
  end;
  
  TForm2 = class(TForm)
    pbCreateFile: TButton;
    dfFileName: TEdit;
    pbReadFile: TButton;
    ListBox1: TListBox;
    procedure pbCreateFileClick(Sender: TObject);
    procedure pbReadFileClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.DFM}

procedure TForm2.pbCreateFileClick(Sender: TObject);
var
  FileS100: file of Str100Type;
  procedure AddRec(ACard,AValueNo:integer; AValue:string);
  var
    VarS100: Str100Type;
  begin
    VarS100.Card := ACard;
    VarS100.ValueNo := AValueNo;
Code:
    // Note: 100 used in next statement instead of 103
    //       leaves three uninitialized bytes at the
    //       end of the string in the buffer.
    //       May or may not be nulls.
Code:
    VarS100.Value := AValue + StringOfChar(' ',
Code:
100
Code:
 - Length(AValue));
    Write(FileS100,VarS100);
  end;
begin
  AssignFile(FileS100, 'c:\test.txt');
  Rewrite(FileS100);
  AddRec(1,21,'Data for record one');
  AddRec(2,22,'Data for record two');
  AddRec(3,23,'Data for record three');
  AddRec(4,24,'Data for record four');
  CloseFile(FileS100);
end;

procedure TForm2.pbReadFileClick(Sender: TObject);
var
  FileS100: file of Str100Type;
  VarS100: Str100Type;
begin
  ListBox1.Clear;
  ListBox1.Tabwidth := 15;
  AssignFile(Files100, dfFileName.Text);
  Reset(FileS100);
  While not Eof(FileS100) do
    begin
      Read(FileS100,varS100);
      ListBox1.Items.Add(IntToStr(VarS100.Card)
        + #9 + IntToStr(VarS100.ValueNo)
        + #9 + VarS100.Value);
    end;
  CloseFile(FileS100);
end;

end.
Is this another case of old code creeping back into the project? Or perhaps, they were old versions of the files.
 
That's strange, they've always been the way they're defined there, I never touched the definitions after first writing them. Everything is read in right, so I assumed they were ok.
 
Three things to consider (I haven't examined all the code posted in this thread):

1) You might be looking at a memory overwrite. The file might not really be closed, the file variable may have been stomped on by something else. This could *LOOK* like a closed file.

2) You may have some code in $I- state that's leaving a pending error that blows up on the next file access. $I- should never be used with Delphi (it's a legacy feature from before exceptions) but some third-party component might have used it.

3) If somehow a copy of a file variable existed and was closed the original would then be closed even though it still shows the file to be open. This would tend to show up as invalid file handle but I've seen other weird things happen. The compiler normally protects you from this but if untyped parameters are ever used in dealing with files (ie, a routine that takes a file of any type as a parameter) it could happen.
 
The problem fixed itself, but just for completeness:

1) Don't think so, but I also thought my file formats were behaving themselves.

2) That's not used, only standard components in my project, and I learnt about that after my last program giving me errors on the wrong files.

3) ??? Don't follow that, so I probably didn't do it.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top