I need one (and only one) command to create a file and if this file still exists creating the file must fail.
If have tried out following code:
DEFINE STREAM osFile.
OUTPUT stream osFile to value(FullFilePath) no-echo.
PUT STREAM osfile SUBSTITUTE("Started at &1", NOW) SKIP.
and not to close the stream after creating the file. Unfortunately another user can invoke the code without getting an excecption file is already in use.
Has anyone an idea how to solve my Problem?
You need an atomic operation and this operation is os-rename.
First you need to create a known unique file. For example, the file name includes a pid, date, time, user number, and so on.
Then this file is renamed. Only one user will see the zero result of the os-error function, which means a successful file creation. Another user will receive the result 10 (File exists).
To check a file exists on disk:
file-info:file-name = FullFilePath.
if file-info:full-pathname = ? then
/* file path specified does not exist */
/* do what you want.*/
message "File already exist!" view-as alert-box.
Russian Progress User Group
thank you for your reply: But I need only ONE command.
Even it is unlikely.When two processes search for the file at exactly the same time, both won't find the file to create.
And then both will create the new file.
When I need to coordinate processes, the simplest is to use a LOCK on a record.
In my case, I do an EXCLUSIVE-LOCK on a system wide config record ('Locking Record') and then check for the existence:
FIND cttConfig WHERE cttConfig.Name = 'Locking' EXCLUSIVE-LOCK NO-WAIT.
FILE-INFO:FILE-NAME = 'File to check'
IF FILE-INFO:FULL-PATHNAME EQ ? THEN
-- do it --
You can wait for the lock, or fail, according to the logic.
My thought indeed. And don't forget a transaction block or otherwise the transaction scope is raised to the entire block which my have some unpleasant side effects.
I do not know off one such command in the ABL. Why do you need exactly one command? Is it a timing issue?
thank you for your reply. That was exactly what I am looking for.
After changing my code to
OS-RENAME value(uniqueFileName) value(FullFilePath).
errorCode = OS-ERROR.
IF (errorCode = 0) THEN
result = TRUE.
WriteError(PROGRAM-NAME(1), SUBSTITUTE("Fehler beim Erzeugen von &1: &2", FullFilePath, errorCode)).
everything works as wished.
Architect of the SmartComponent Library and WinKit
thank you for your answer.
.Net is an option but as often as possible I try to use ABL-commands. And as far as I can see the solution with ABL works without any problems.