If you want to use TFileStream.Create then bung it in a Try/Except -
if you use the Native FileOpen then there will be no exceptions
Here is what I use for opening files - outside boxed up types:-
unit FileUtil;
(* File Utilities - 19/2/01 JF
*)
interface
uses
Windows, SysUtils, Classes, Minimsg, UsLib;
Function FileLen( Fle:String ):Integer; // Get File Length
Function OpenErr( Const Fle, OpenMode:String; Var Handle:Integer
):Boolean;
Function ErrMsg:String;
Function CopyDateErr( SrcHandle, DestHandle:Integer ):Boolean;
implementation
Function LS_GetFlag( Var Mode:String; Const Flag:String
):Boolean;Forward;
{
########################################################################
Function FileLen( Fle:String ):Integer;
var
L9 : Integer;
Handle: THandle;
FindData: TWin32FindData;
begin
Result := -1;
{ Check for '*' and '?' }
For L9 := 1 To Length( Fle ) Do
If ( Fle[L9] = '*' ) Or ( Fle[L9] = '?' ) Then
Exit;
Handle := FindFirstFile(PChar(Fle), FindData);
if Handle <> INVALID_HANDLE_VALUE then
begin
Windows.FindClose(Handle);
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0
then
begin
Result := FindData.nFileSizeLow ; // Note - Up to 2 Gb
Exit;
end;
end;
End;
{
const fmOpenRead = $0000;
const fmOpenWrite = $0001;
const fmOpenReadWrite = $0002;
const fmShareCompat = $0000;
const fmShareExclusive = $0010;
const fmShareDenyWrite = $0020;
const fmShareDenyRead = $0030;
const fmShareDenyNone = $0040;
{
########################################################################
Var
FErrMsg : String ;
Function ErrMsg:String;
Begin
Result := FErrMsg ;
End;
{
########################################################################
Mode : 'IORW L LR LW' Input Output Lock LockRead LockWrite /
Shared
Note : O Creates File and Opens in RW Mode (18/3/01 JF)
Function OpenErr( Const Fle, OpenMode:String; Var Handle:Integer
):Boolean;
Var
Mode : String ;
RW, Share : Integer ;
CreateFlag : Boolean ;
ReadFlag : Boolean ;
WriteFlag : Boolean ;
Begin
Result := True ;
Mode := OpenMode ;
CreateFlag := (InStr( Mode, 'O' ) > 0) ; // 'O'utput
// Default to Shared
Share := fmShareDenyNone ;
If LS_GetFlag( Mode, 'LR' ) Then
Share := fmShareDenyRead ;
If LS_GetFlag( Mode, 'LW' ) Then
Share := fmShareDenyWrite ;
If LS_GetFlag( Mode, 'L' ) Then
Share := fmShareExclusive ;
ReadFlag := False ;
WriteFlag := False ;
If LS_GetFlag( Mode, 'W' ) Then // Write
WriteFlag := True ;
If LS_GetFlag( Mode, 'R' ) Then // Read
ReadFlag := True ;
If LS_GetFlag( Mode, 'I' ) Then // Input - Read
ReadFlag := True ;
If LS_GetFlag( Mode, 'O' ) Then // Output - Write + Create
Begin
ReadFlag := True ; // Best set this for Buffered
Access
WriteFlag := True ;
End;
RW := -1 ;
If ReadFlag Then
RW := fmOpenRead ;
If WriteFlag Then
RW := fmOpenWrite ;
If ReadFlag Then
If WriteFlag Then
RW := fmOpenReadWrite ;
If RW = -1 Then
MiniMessage( 'FileUtil.Open', Fle + #13 + 'Neither Read or Write
Mode Requested' ) ;
// Create
If CreateFlag Then
Begin
Handle := FileCreate( Fle ) ;
If Handle <= 0 Then
Begin
FErrMsg := 'Error Creating File [' + Fle + '] ' + IntToStr(
Handle ) ;
If FileExists( Fle ) = False Then
FErrMsg := FErrMsg + ' - File Not Present'
Else
FErrMsg := FErrMsg + ' - Access Denied' ;
Exit;
End;
FileClose( Handle ); // So we suceeded - close file
End;
// Now Open the File
Handle := FileOpen( Fle, RW Or Share ) ;
If Handle <= 0 Then
Begin
FErrMsg := 'Error Opening File [' + Fle + '] ' + IntToStr( Handle
) ;
If FileExists( Fle ) = False Then
FErrMsg := FErrMsg + ' - File Not Found'
Else
FErrMsg := FErrMsg + ' - Access Denied' ;
Exit;
End;
// Good Exit
Result := False ;
End;
{
########################################################################
Check for Substring & Zap if Found
Function LS_GetFlag( Var Mode:String; Const Flag:String ):Boolean;
Var
Q : Integer ;
Begin
Result := False ;
Q := InStr( Mode, Flag ) ;
If Q <> 0 Then
Begin
MidSet( Mode, Q, StringOf( Length(Flag), Ord('x') ) ) ;
Result := True ;
End;
End;
{
########################################################################
Copy File Date from one open file to another
Function CopyDateErr( SrcHandle, DestHandle:Integer ):Boolean ;
Var
Q : Integer ;
Begin
Result := True ;
Q := FileGetDate( SrcHandle ) ;
If Q = -1 Then
Begin
FErrMsg := 'CopyDateErr - bad Source Handle' ;
Exit;
End;
If FileSetDate( DestHandle, Q ) <> 0 Then
Begin
FErrMsg := 'CopyDateErr - bad Source Handle' ;
Exit;
End;
// Good Exit
Result := False
End;
end.
On Thu, 21 Jun 2001 09:37:38 -0700, "Bob Richardson"
Quote
<b...@whidbey.com> wrote:
>> The native FileOpen stuff is what Windows really uses, and that what I
>> am used to - I like the fact that it does not raise exceptions -
>> rather it returns 'implied' errors.
>But I'm getting an error message "Cannot open file Myfile.txt"
>I run the same program twice. The purpose of the "ShowMessage" is to freeze
>the program in the update mode, so that I can make sure that the second
>running of the program will find AFile open. Sure enough, I get a Window's
>error message. What have I done wrong? Here's the code.
> repeat
> STM := tFileStream.create(AFile, fmOpenReadWrite or fmShareExclusive);
> if STM.Handle <= 1 then begin
> ShowMessage('Please wait, '+AFile+' in use'); // this never appears
> STM.free;
> end;
> until STM <> nil;
> with stl do begin // stl is a stringlist that was created earlier
> clear;
> LoadFromStream(STM);
> add(Data.text); // simple update for testing
> STM.Position := 0;
> ShowMessage('press to update'); // freezes program
> SavetoStream(STM);
> end;
> STM.free;
> Display stl in stringgrid