Best (fastest) way to check a valid file or drawer?

13 posts / 0 new
Last post
jabirulo
jabirulo's picture
Offline
Last seen: 3 weeks 1 day ago
Joined: 2013-05-30 00:53
Best (fastest) way to check a valid file or drawer?

Hi, what's the best (and if possible fastest) way to check for a valid file or drawer?

Using IDOS->Open()?
Using IDOS->Lock()?
Using IDOS->ExamineObject()?

Pros and Cons about above methods?

Now I'm using Open():

  1. BPTR FileExists(CONST_STRPTR srcdir, CONST_STRPTR srcfile, STRPTR destpath, int32 path_size)
  2. {
  3. BPTR fh;
  4.  
  5. IUtility->Strlcpy(destpath, srcdir, path_size);
  6. IDOS->AddPart(destpath, srcfile, path_size);
  7. fh = IDOS->Open(destpath, MODE_OLDFILE);
  8. IDOS->Close(fh);
  9. //IDOS->Printf("[%lx]'%s'\n",fh,destpath);
  10. return fh;
  11. }

TIA

thomas
thomas's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2011-05-16 14:23
Open -> only works on files.

Open -> only works on files. Open() on a directory fails.
Lock -> works on files and directories but does not tell you what it is.
ExamineObject -> works on both and tells you the type of the object

Speedwise I would say that Lock is fastest, Open is slowest and ExamineObject is somewhere inbetween.

jabirulo
jabirulo's picture
Offline
Last seen: 3 weeks 1 day ago
Joined: 2013-05-30 00:53
ok, thx will do some tests

ok, thx will do some tests and see what happens.

AOS4.1/SAM460ex/PPC460EX-1155MHZ/2048MB/RadeonHD6570/SSD120GB/DVDRW :-P

hypex
hypex's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 2011-09-09 16:20
Open() is unsuitable and

Open() is unsuitable and Lock() has the problem of using Examine() with it being old and not liked by newer OS and SDK versions. Given you must allocate a FIB for use with Examine() as well you might as well use ExamineObject() if your code targets OS4.1. It's also less code to type as some things are done internally.

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
@thomas To add to what you

@thomas

To add to what you wrote Open() will also work with handlers which do not support locking (like DEV:, HTTP:, RANDOM:, AUDIO:, etc.) whereas Lock() will not.

Also the Open() method needs less code to be written and I doubt it is much slower than using ExamineObjectTags() which is also overkill for this purpose (ultimately which of these methods is faster/slower is very much dependent on the filesystem used).

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
@hypex Lock() has the

@hypex


Lock() has the problem of using Examine() with it being old and not liked by newer OS and SDK versions.

No idea what you are implying here. ExamineObjectTags() can be used with either a lock (EX_LockInput), a file handle (EX_FileHandleInput) or a string path to the object in question (EX_StringNameInput) in which case Lock()/Open() is called internally by the function.

Essentially it's a large file supporting replacement for the old and now obsolete Examine()/ExamineFH() functions.

jabirulo
jabirulo's picture
Offline
Last seen: 3 weeks 1 day ago
Joined: 2013-05-30 00:53
Did some test using

Did some test using IDOS->Lock() and IDOS->Open(). Lock() seems a bit faster.

Various IDOS->Lock() results:
_RunTime 0.007032
_RunTime 0.007129
_RunTime 0.007078

Various IDOS->Open() results:
_RunTime 0.007091
_RunTime 0.007273
_RunTime 0.007037

Source code used, is part of the one I use on Mixer.docky:

  1. ;/*
  2. gcc -N -Wall -o TESTlockopen TESTlockopen.c -gstabs
  3. quit
  4. */
  5.  
  6. #include <proto/exec.h>
  7. #include <proto/dos.h>
  8. #include <proto/utility.h>
  9.  
  10. BPTR FileExists(CONST_STRPTR dir, CONST_STRPTR file, STRPTR path, int32 path_size);
  11. BOOL FindImage(CONST_STRPTR image, STRPTR path, int32 path_size);
  12.  
  13. //struct Library *DOSBase = NULL;
  14. struct Library *UtilityBase = NULL;
  15.  
  16. //struct DOSIFace *IDOS = NULL;
  17. struct UtilityIFace *IUtility = NULL;
  18.  
  19. STRPTR fullpath; // used in FindImage()
  20.  
  21.  
  22. int main(void)
  23. {
  24. STRPTR mypath = IExec->AllocVecTags(1024, TAG_END);
  25.  
  26. DOSBase = IExec->OpenLibrary("dos.library", 52);
  27. IDOS = (struct DOSIFace *)IExec->GetInterface(DOSBase, "main", 1, NULL);
  28.  
  29. UtilityBase = IExec->OpenLibrary("utility.library", 53);
  30. IUtility = (struct UtilityIFace *)IExec->GetInterface(UtilityBase, "main", 1, NULL);
  31.  
  32. fullpath = IExec->AllocVecTags(1024, TAG_END);
  33. IUtility->Strlcpy(fullpath, "tbimages:", 1024); // see FindImage()
  34.  
  35. IDOS->Printf( "FindImage()=%ld\n",FindImage("sound", mypath, 1024) );
  36.  
  37. IExec->FreeVec(mypath);
  38. IExec->FreeVec(fullpath);
  39.  
  40. IExec->DropInterface( (struct Interface *)IUtility );
  41. IExec->CloseLibrary(UtilityBase);
  42.  
  43. IExec->DropInterface( (struct Interface *)IDOS );
  44. IExec->CloseLibrary(DOSBase);
  45.  
  46. return(0);
  47. }
  48.  
  49.  
  50. BPTR FileExists(CONST_STRPTR dir, CONST_STRPTR file, STRPTR path, int32 path_size)
  51. {
  52. BPTR result;
  53.  
  54. IUtility->Strlcpy(path, dir, path_size);
  55. IDOS->AddPart(path, file, path_size);
  56.  
  57. //result = IDOS->Open(path, MODE_OLDFILE);
  58. //IDOS->Close(result);
  59.  
  60. result = IDOS->Lock(path, SHARED_LOCK);
  61. IDOS->UnLock(result);
  62.  
  63. return result;
  64. }
  65.  
  66.  
  67. BOOL FindImage(CONST_STRPTR image, STRPTR path, int32 path_size)
  68. {
  69. BOOL val = FALSE;
  70. STRPTR temppath = IExec->AllocVecTags(path_size, TAG_END);
  71.  
  72. IUtility->Strlcpy(temppath, fullpath, path_size);
  73. if( FileExists(temppath, image, path, path_size) )
  74. val = TRUE; // aka PROGDIR:
  75. else
  76. {
  77. IDOS->AddPart(temppath, "Images/", path_size);
  78. if( FileExists(temppath, image, path, path_size) )
  79. val = TRUE; // aka PROGDIR:Images/
  80. else
  81. if( FileExists("TBImages:", image, path, path_size) )
  82. val = TRUE;
  83. else
  84. *path = '\0';
  85. }
  86.  
  87. IExec->FreeVec(temppath);
  88. return val;
  89. }

AOS4.1/SAM460ex/PPC460EX-1155MHZ/2048MB/RadeonHD6570/SSD120GB/DVDRW :-P

xenic
xenic's picture
Offline
Last seen: 2 years 7 months ago
Joined: 2011-05-07 04:52
@jabirulo If open() will

@jabirulo
If open() will succeed with handlers but lock() will not (as salass00 says), then combining Lock() and OpenFromLock() might be the fastest way to determine if an object exists and if it's a file or directory. Using Lock() first will succeed if a file or directory exists and using OpenFromLock() next will only succeed if the object is a file. Because ExamineObject() requires a subsequent call to FreeDosObject(), calls Lock() and UnLock() with filename input, and calls Open() & Close() if the filename is a handler, it might actually be faster to use a Lock()/OpenFromLock() combination in your code.

In other words, instead of using ExamineObject() it might be faster to use something like:
if (mylock=Lock("filename",SHARED_LOCK))
{
if (handle=OpenFromLock(mylock))
{
IsFile=TRUE;
Close(handle);
}
Unlock(mylock);
}
I'll leave it up to you to see which way is faster.

P.S. Since "-lauto" is now implicit if you don't use -nostartfiles or -nostartlibs, you don't need to open any libraries in your example code.

X1000 - OS 4.1FE

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
@xenic Colin Wenzel doesn't

@xenic

Colin Wenzel doesn't have an account here but has asked me to reply.

I'm quoting from his e-mail:


Xenic has replied with an OpenFromLock() option, however his code
is UnLock()'ing the lock when the OpenFromLock() succeeded,
which will crash.

Also, up until when I fixed CrossDOSFileSystem @ 53.11,
it would actually succeed in opening a directory lock. (":[]

So make sure that UnLock() is only called when OpenFromLock() fails and you should be fine. That is unless you are using this method with CrossDOSFileSystem older than 53.11.

xenic
xenic's picture
Offline
Last seen: 2 years 7 months ago
Joined: 2011-05-07 04:52
@salass00 Thanks to you and

@salass00
Thanks to you and Colin for pointing out my oversight. I couldn't find any way to edit my original post so I'll repost a corrected version here:

  1. if (mylock=Lock("filename",SHARED_LOCK))
  2. {
  3. if (handle=OpenFromLock(mylock))
  4. {
  5. IsFile=TRUE;
  6. Close(handle);
  7. }
  8. else
  9. Unlock(mylock);
  10. }

It's just a code snippit that is hopefully correct now:-)

I wonder how AmigaDOS reacts when you try to write to an opened directory on an old CrossDOSFileSystem?

X1000 - OS 4.1FE

jabirulo
jabirulo's picture
Offline
Last seen: 3 weeks 1 day ago
Joined: 2013-05-30 00:53
Using

Using 'IDOS->ExamineObjectTags()' seems as fast as 'IDOS->Open()':
_RunTime 0.007175
_RunTime 0.007393
_RunTime 0.007289

  1. BPTR FileExists(CONST_STRPTR s_dir, CONST_STRPTR s_file, STRPTR d_path, int32 d_path_size)
  2. {
  3. BPTR result = 0;//, handle;
  4. struct ExamineData *dat;
  5.  
  6. IUtility->Strlcpy(d_path, s_dir, d_path_size);
  7. if(*s_file)
  8. IDOS->AddPart(d_path, s_file, d_path_size);
  9.  
  10. // result = IDOS->Open(d_path, MODE_OLDFILE);
  11. // IDOS->Close(result);
  12. /*
  13.  if( (result=IDOS->Lock(d_path, SHARED_LOCK)) )
  14.  {
  15.   if( (handle=IDOS->OpenFromLock(result)) )
  16.   IDOS->Close(handle);
  17.   else
  18.   {
  19.   IDOS->UnLock(result);
  20.   result = -1;
  21.   }
  22.  }
  23. */
  24. if( (dat=IDOS->ExamineObjectTags(EX_StringNameInput,d_path, TAG_END)) )
  25. {
  26. if( EXD_IS_DIRECTORY(dat) )
  27. result = -1;
  28. else
  29. if( EXD_IS_FILE(dat) )
  30. result = 1;
  31.  
  32. IDOS->FreeDosObject(DOS_EXAMINEDATA,dat);
  33. }
  34.  
  35. return result;
  36. }

THX for all help guys!

AOS4.1/SAM460ex/PPC460EX-1155MHZ/2048MB/RadeonHD6570/SSD120GB/DVDRW :-P

hypex
hypex's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 2011-09-09 16:20
@salass00 No idea what you

@salass00

No idea what you are implying here.

What I was implying is that if Lock() is used then Examine() would be the next step. I didn't take ExamineObjectTags() into consideration as you can give it a file name and skip any need to lock an object. And in the OP a file name was being used.

hypex
hypex's picture
Offline
Last seen: 3 months 3 weeks ago
Joined: 2011-09-09 16:20
When there is a post after

When there is a post after yours I found your post is locked.

Regarding OpenFromLock() and freeing the lock. I have got caught on this myself. On a real Amiga with SFS used, it can freeze the system. On OS4 it will crash. If you look up the API docs you will see that it tells you not to free the lock on success. Funny how we have these slight overights on the docs that can have bigger consequences. :-)

Log in or register to post comments