Press enter to see results or esc to cancel.

File Operations

Turbo Pascal needs to create, read from and write to files. Few simple routins take care for this.

Procedure OpenFile (Var FileToOpen: File; FileName: PChar);
Var Error: Integer;
begin
  Assign (FileToOpen, FileName);
{$I-}
  Repeat
    Reset (FileToOpen, 1);
    Error := IOResult;
    Case Error of
      0: Exit;
      2: FileError (FileName, FileNotFound);
      4: If not CloseOneSourceFile then FileError (FileName, TooManyOpenFiles);
      5: FileError (FileName, FileAccessDenied);
      else FileError (FileName, InvalidFilename);
    end;
  until False;
{$I+}
end;

Procedure CreateFile (Var FileToCreate: File; FileName: PChar);
Var Error: Integer;
begin
  Assign (FileToCreate, FileName);
{$I-}
  Repeat
    Rewrite (FileToCreate, 1);
    Error := IOResult;
    Case Error of
      0: Exit;
      2: FileError (FileName, FileNotFound);
      4: If not CloseOneSourceFile then FileError (FileName, TooManyOpenFiles);
      5: FileError (FileName, FileAccessDenied);
      else FileError (FileName, InvalidFilename);
    end;
  until False;
{$I+}
end;

Procedure DeleteFile (FileName: PChar);
Var TempFile: File;
begin
  Assign (TempFile, FileName);
  {$I-}
    Close (TempFile);
    Erase (TempFile);
  {$I+}
end;

If there are too many files open Turbo Pascal tries to close them one by one and repeat requested file operation before reporting an error.

Function CloseOneSourceFile: Boolean;
Var CurrentFileStructPtr, NextFileStructPtr: PFileStructure;
    TempHandle: Word;
begin
  CloseOneSourceFile := False;
  If CurrentSourceFile = @EndOfFileStructure then Exit;
  NextFileStructPtr := Ptr (Seg (FileStructure), CurrentSourceFile^.Name.Len + Ofs (CurrentSourceFile^.Name.Chr));
  If Ofs (NextFileStructPtr^) = Ofs (EndOfFileStructure) then Exit;
  Repeat
    CurrentFileStructPtr := NextFileStructPtr;
    NextFileStructPtr := Ptr (Seg (FileStructure), CurrentFileStructPtr^.Name.Len + Ofs (CurrentFileStructPtr^.Name.Chr));
    If Ofs (NextFileStructPtr^) = Ofs (EndOfFileStructure) then Break;
  until NextFileStructPtr^.Handle = 0;
  TempHandle := CurrentFileStructPtr^.Handle;
  CurrentFileStructPtr^.Handle := 0;
  If TempHandle <> 0 then
    Asm
      MOV  BX, TempHandle
      MOV  AH, $3E
      INT  $21
      CLD
    end;
  CloseOneSourceFile := True;
end;

Turbo Pascal always reads all files as binary ones. It processes them on the lowest level.

Function ReadFile (Var FileToRead: File): Pointer;
Var FSize: Longint;
    BytesRead: Word;
begin
  FSize := FileSize (FileToRead) - FilePos (FileToRead);
  If FSize > 16 * LongInt (HeapEndRec.Seg - HeapPtrRec.Seg) then Error (OutOfMemory);
  ReadFile := HeapPtr;
  Repeat
    BlockRead (FileToRead, HeapPtr^, $FFF0, BytesRead);
    FSize := FSize - BytesRead;
    HeapPtrRec.Seg := HeapPtrRec.Seg + (BytesRead + $000F) shr 4;
  until FSize = 0;

end;