Create a file only one time

Posted by Kai Siegele on 11-Apr-2017 04:51

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

Posted by OlegM on 11-Apr-2017 05:59

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).

All Replies

Posted by Valeriy Bashkatov on 11-Apr-2017 05:17

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.

Posted by Kai Siegele on 11-Apr-2017 05:31

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

Posted by David Abdala on 11-Apr-2017 05:42

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.

Posted by bronco on 11-Apr-2017 05:55

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.

Posted by martinz on 11-Apr-2017 05:56

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

Posted by OlegM on 11-Apr-2017 05:59

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).

Posted by Kai Siegele on 11-Apr-2017 08:14

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

Posted by Mike Fechner on 11-Apr-2017 21:30

Is .NET Code an option? When using .NET streams you can define exclusive access and it will throw an error when not possible.

Posted by Kai Siegele on 12-Apr-2017 01:46

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

This thread is closed