Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2015-11

Safe temp file name

12 messages · 5 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Aradeonas

Hi,

I used?GetTempFileName in a multi thread system and it causes problems as you guess already. So the best way in my mind is using GUID and maybe use it in a loop for checking not existing for extra safety. But I want to know is there any clean implementation already that I dont know of?

Regards, Ara

http://www.fastmail.com - The way an email service should be -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151125/aa58f418/attachment.html>

Reply by email

Graeme Geldenhuys
to Aradeonas
Aradeonas wrote
So the best way in my mind is using GUID and maybe use it in a loop for checking not existing for extra safety.

I've used GUID's as temp file names in a CGI application for about 5 years. The CGI app gets accessed all at the same time in a classroom environment by about 30-80 kids. I've never hit a duplicate GUID issue. I'm not saying it is impossible, I'm just saying the chances are very very slim.

In tiOPF I also use GUID's as Object ID's. I've multiple times imported data which generates about 80,000-100,000 objects in memory in an instant. Again, used this software for many years, and never hit a single duplicate GUID.

So I think it is a pretty safe option to use as a temp file name, even in a multi-threaded environment.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email

Graeme Geldenhuys
to Aradeonas
Aradeonas wrote
Can you point me to where this system implemented in tiOPF?

This function returns a GUID value:

http://sourceforge.net/p/tiopf/code/ci/tiopf2/tree/Core/tiUtils.pas#l3837

This is the class in tiOPF that uses GUID's. This class strips out the '{', '-' and '}' symbols from a standard GUID string so that only the numbers and letters get used.

http://sourceforge.net/p/tiopf/code/ci/tiopf2/tree/Core/tiOIDGUID.pas

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email

Tony Whyman
to Aradeonas: I used?GetTempFileName in a multi thread system and it causes problems as you guess…

This may be an appropriate use for EnterCriticalSection and ExitCriticalSection, although why don't you just use a different "prefix" in the call to GetTempFile for each thread.

Aradeonas wrote 18 lines
Hi, I used GetTempFileName in a multi thread system and it causes problems as you guess already. So the best way in my mind is using GUID and maybe use it in a loop for checking not existing for extra safety. But I want to know is there any clean implementation already that I dont know of? Regards, Ara -- http://www.fastmail.com - The way an email service should be -- _______________________________________________ Lazarus mailing list http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151125/271936cd/attachment.html>

Reply by email

Rik van Kekem
to Graeme Geldenhuys: I've used GUID's as temp file names in a CGI application for about 5 years. The CGI app…
Aradeonas wrote
I used GetTempFileName in a multi thread system and it causes problems as you guess already.

I wasn't aware that GetTempFileName isn't threadsafe. (Are you sure your code is correct?)

Graeme Geldenhuys wrote 6 lines
On 2015-11-25 13:51, Aradeonas wrote: > So the best way in my mind is using GUID and maybe > use it in a loop for checking not existing for extra safety. So I think it is a pretty safe option to use as a temp file name, even in a multi-threaded environment.

Even Microsoft advises it in case you use GetTempFileName excessively.

Due to the algorithm used to generate file names, *GetTempFileName*

can perform poorly when creating a large number of files with the same prefix. In such cases, it is recommended that you construct unique file names based on *GUID*s.
So it should be safe to use GUIDs for tempfilenames.

FPC trunk has this:
   Guid := TGUID.NewGuid.toString;

(I'm not sure if FPC 2.6.4 also some helpers for creating GUIDs)

Grtz,
Rik (rvk)

Reply by email

Rik van Kekem
to Rik van Kekem
Rik van Kekem wrote
(I'm not sure if FPC 2.6.4 also some helpers for creating GUIDs)

This will work in FPC 2.6.4:

var
   GUID : TGUID;
begin
   if CreateGUID(GUID) = 0 then
   begin
     MyFileName := GuiDToString(Guid);
   end;

You could strip the {, } and - if you want.

Grtz,
Rik (rvk)

Reply by email

Aradeonas
to Rik van Kekem

Thanks Graeme,Its like what I do so it seems Im doing OK. I looked at the code and it seems it just remove { and }.

if (LValue[1] = '{') and? ? (LValue[cGUIDLength] = '}') then? ? LValue := Copy(lValue, 2, cGUIDLength - 2);? AAssignTo.AsString := LValue;

It seems it doesnt remove "-" .

This may be an appropriate use for EnterCriticalSection and ExitCriticalSection, although why don't you just use a different "prefix" in the call to GetTempFile for each thread.

Yes I can but GUID is easier to use.

I wasn't aware that GetTempFileName isn't threadsafe.

(Are you sure your code is correct?) Yea. If you look at the implementation it just check until there isnt a file so if 2 thread get a filename before they create it it cause a problem. In my case I made 100 thread and they will create temp file and use them,simple but some time it will happen.

var
   GUID : TGUID; begin if CreateGUID(GUID) = 0 then begin  MyFileName :=
   GuiDToString(Guid); end;

Thanks.

Regards, Ara

http://www.fastmail.com - mmm... Fastmail... -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20151125/9508adcf/attachment.html>

Reply by email

Graeme Geldenhuys
to Aradeonas
Aradeonas wrote
> > if (LValue[1] = '{') and (LValue[cGUIDLength] = '}') then LValue > > := Copy(lValue, 2, cGUIDLength - 2); AAssignTo.AsString := LValue; It seems it doesnt remove "-" .

Oops, my mistake. Yes, only { and } is removed in tiOPF code.

Regards,
- Graeme -

Reply by email

Henry Vermaak
to Aradeonas: I used?GetTempFileName in a multi thread system and it causes problems as you guess…
Aradeonas wrote 6 lines
Hi, I used?GetTempFileName in a multi thread system and it causes problems as you guess already. So the best way in my mind is using GUID and maybe use it in a loop for checking not existing for extra safety. But I want to know is there any clean implementation already that I dont know of?

It's pointless to check whether the file exists, since there's a race between checking whether the file exists and creating/using it.

You need something that creates the file atomically only if it doesn't exist. For posix use open(2) with O_CREAT | O_EXCL. For Windows use CreateFile() with CREATE_NEW. When this fails, try again with another file name.

Henry

Reply by email

Graeme Geldenhuys
to Rik van Kekem: Why are the { and } actually removed? As far as I know they can be part of a filename on…
Rik van Kekem wrote
Why are the { and } actually removed? As far as I know they can be part of a filename on all OSes (or am I wrong?)

In tiOPF (the code I linked too), GUID's are used as an OID (Object ID), and normally stored in a database field of type char(36). The { and } was simply removed to save 2 bytes per record. I guess the "-" symbol was left in place to make reading the OIDs (by a human) a bit easier - most likely for debugging purposes only.

As for using the GUID value as a file name... I always followed the example of tiOPF, but yes, modern file systems will allow the { and } symbols in the file name without problem.

Regards,
- Graeme -

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp

Reply by email