Create a file only one time - Forum - OpenEdge Development - Progress Community
 Forum

Create a file only one time

This question is answered

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

Verified Answer
  • 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
  • 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

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

    Architect of the SmartComponent Library and WinKit

    Consultingwerk Ltd.

  • 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