Hallo,
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?
Best regards
Kai
Hi,
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).
Hi,
To check a file exists on disk:
file-info:file-name = FullFilePath.
if file-info:full-pathname = ? then
do:
/* file path specified does not exist */
/* do what you want.*/
end.
else
do:
message "File already exist!" view-as alert-box.
end.
Hallo Valeriy,
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.
Best regards
Kai
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 --
END.
RELEASE cttConfig.
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.
Hi Kai,
I do not know off one such command in the ABL. Why do you need exactly one command? Is it a timing issue?
- Martin
Hi,
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).
Hallo Oleg,
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.
ELSE
WriteError(PROGRAM-NAME(1), SUBSTITUTE("Fehler beim Erzeugen von &1: &2", FullFilePath, errorCode)).
everything works as wished.
Best regards
Kai
Hallo Mike,
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.
Best regards
Kai