Reputation:
I want to create a .txt
file and write to it at any moment at run-time. To do this, I'm using the AssignFile()
function. But I am having trouble in instances where my file already exists. I get an error that says: File access denied.
To better explain, see these two examples:
Ex1: if I call AssignFile()
the first time when the file does not exist, OK! But, if the file exists, this does not work.
Ex2: if I call AssignFile()
the second time (when AssignFile()
was successful the first time), this also does not work.
Is this a bug in the AssignFile()
function?
var
myfile: TextFile;
Procedure WriteFileContent(const MyTxtFile: string; MyNumber: DWORD);
var
F: TextFile;
Begin
If FileExists(MyTxtFile) Then
Begin
AssignFile(F, MyTxtFile);
Rewrite(F);
Writeln(F, '0x' + IntToHex(MyNumber,8));
CloseFile(F);
End;
End;
begin
try
// Calling AssignFile() by first time
AssignFile(myfile, 'myfile.txt');
Rewrite(myfile);
CloseFile(myfile);
setfileattributes('myfile.txt', FILE_ATTRIBUTE_HIDDEN);
Sleep(5000);
// Calling AssignFile() by second time
WriteFileContent('myfile.txt', 123456789);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
Upvotes: 4
Views: 4675
Reputation: 21033
It is not AssignFile()
that fails, but your call to Rewrite()
on a file with the Hidden
attribute set. Following explains it:
Typically you call Rewrite(F)
in order to erase the file and write new data to it with subsequent Write(F, ...)
or WriteLn(F, ...)
calls.
From docs (System.Rewrite):
If an external file with the same name already exists, it is deleted and a new empty file is created in its place.
There is no problem opening the file for writing with the Append()
command.
(Based on above I drew the conclusion that it is the deletion that fails with the Access denied message. That was cutting the corners too much.)
Beaten by comments I traced through the code and compared actual code with MSDN documentation for CreateFile:
Actual code:
// if mode is fmOutput (as it is for Rewrite)
OpenMode = GENERIC_WRITE
Flags = CREATE_ALWAYS
// ...
Temp := CreateFile(t.Name, OpenMode, FILE_SHARE_READ, nil, Flags, FILE_ATTRIBUTE_NORMAL, 0);
And documentation:
If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile fails and sets the last error to ERROR_ACCESS_DENIED if the file exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM attribute.
Calling Rewrite()
on a existing file with the hidden
attribute fails always.
Upvotes: 7