Test if a directory exists
Test if a directory exists
Ho do you test if a directory exists ?
FOP_DIR does not seem to work.
If i try
c%=FOP_DIR('win2_XYZ'_): Print c%
it returns a positive number even if the directory win2_XYZ_ does not exist - it simply opens a channel to win2_
If i try
c%=FOP_DIR('win27_XYZ'_): Print c%
it returns a positive number even if the drive win27_ cannot exist - it simply opens a channel to the default drive
So how can you check if a directory exists or not ?
FOP_DIR does not seem to work.
If i try
c%=FOP_DIR('win2_XYZ'_): Print c%
it returns a positive number even if the directory win2_XYZ_ does not exist - it simply opens a channel to win2_
If i try
c%=FOP_DIR('win27_XYZ'_): Print c%
it returns a positive number even if the drive win27_ cannot exist - it simply opens a channel to the default drive
So how can you check if a directory exists or not ?
-
- RWAP Master
- Posts: 2847
- Joined: Sun Nov 28, 2010 4:51 pm
- Location: Stone, United Kingdom
- Contact:
Re: Test if a directory exists
Yes - this is unfortunate - Note 4 on OPEN_DIR in the SBASIC/SuperBASIC Reference Manual refers to it:
https://superbasic-manual.readthedocs.i ... l#open-dir
I don't recall finding a solution (does setting DATA_USE "" help?)
From memory I could not think of a situation where you needed to do this - there is a backup routine in the examples for FBKDT which works the opposite way - starting at the drive and stepping through sub-directories as it goes...
https://superbasic-manual.readthedocs.i ... ists#fbkdt
https://superbasic-manual.readthedocs.i ... l#open-dir
I don't recall finding a solution (does setting DATA_USE "" help?)
From memory I could not think of a situation where you needed to do this - there is a backup routine in the examples for FBKDT which works the opposite way - starting at the drive and stepping through sub-directories as it goes...
https://superbasic-manual.readthedocs.i ... ists#fbkdt
Rich Mellor
RWAP Software
RWAP Adventures
SellMyRetro
Retro-Printer Module - add a USB printer to your QL
Also Involved in:
Icephorm
RWAP Software
RWAP Adventures
SellMyRetro
Retro-Printer Module - add a USB printer to your QL
Also Involved in:
Icephorm
Re: Test if a directory exists
Setting DATA_USE "" does not help - FOP_DIR will open a channel to the drive and will not return -7
I have read about OPEN_DIR and FBKDT - in fact i have started from the OPEN_DIR example and refined it a bit. And I have a couple of cases where it would be nice to check if a directory or a file exists.
Of course, there always are work-arounds - but starting from the drive and parsing the directory tree is a bit time consuming and i wanted to avoid that.
(just for fun I am writing sort of a Norton Commander for the QL)
By the way, DJ_OPEN_DIR has the same behavior and limitations.
I have read about OPEN_DIR and FBKDT - in fact i have started from the OPEN_DIR example and refined it a bit. And I have a couple of cases where it would be nice to check if a directory or a file exists.
Of course, there always are work-arounds - but starting from the drive and parsing the directory tree is a bit time consuming and i wanted to avoid that.
(just for fun I am writing sort of a Norton Commander for the QL)
By the way, DJ_OPEN_DIR has the same behavior and limitations.
Re: Test if a directory exists
The behavior you see has to do with the fact that opening a directory on a valid and working device may not fail on QDOS for reasons other than the file exists and is no directory (That has to do with the fact that directories were a late addition to the OS and also somewhat with the way the default drives and directories work in QDOS) - If the directory you asked for didn't open, the driver will open the directory "next up" for you, walking upwards to the root in case that fails.
What you can always do is:
Though this might still fail on aliased devices like dev_ and pth_, it is much better than nothing.
Tobias
What you can always do is:
- Open the directory
- Check the name of what has been opened against your desired name
Code: Select all
FUNCTION DirExists (name$)
LOCAL channel, realName$
channel = FOP_DIR (name$)
realName$ = FNAME$ (#channel)
CLOSE #channel
IF realName$ == name$ THEN
RETURN 1
ENDIF
RETURN 0
ENDDEF
Tobias
Last edited by tofro on Fri Oct 05, 2018 11:39 pm, edited 2 times in total.
ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Re: Test if a directory exists
I suppose you could try something like this, but only on a level 2 filing system.
100 drive$ = 'win1_':direc$ = 'xyz'
110 ch = FOP_DIR(drive$&direc$)
120 IF FNAME$(#ch) == direc$ THEN
130 PRINT direc$;' exists'
140 ELSE
150 PRINT direc$;' does not exist'
160 END IF
170 CLOSE
or alternatively, use the FMAKE_DIR function version of MAKE_DIR (not all file systems have FMAKE_DIR) to try to create the directory:
er = FMAKE_DIR('win1_xyz_')
IF er = -8 THEN PRINT 'xyz already exists'
On systems not having FMAKE_DIR, you could try error trapping a MAKE_DIR statement, e.g. with Q_ERR_ON 'make_dir' from QLiberator, or a WHEN_ERROR in Turbo.
100 drive$ = 'win1_':direc$ = 'xyz'
110 ch = FOP_DIR(drive$&direc$)
120 IF FNAME$(#ch) == direc$ THEN
130 PRINT direc$;' exists'
140 ELSE
150 PRINT direc$;' does not exist'
160 END IF
170 CLOSE
or alternatively, use the FMAKE_DIR function version of MAKE_DIR (not all file systems have FMAKE_DIR) to try to create the directory:
er = FMAKE_DIR('win1_xyz_')
IF er = -8 THEN PRINT 'xyz already exists'
On systems not having FMAKE_DIR, you could try error trapping a MAKE_DIR statement, e.g. with Q_ERR_ON 'make_dir' from QLiberator, or a WHEN_ERROR in Turbo.
--
All things QL - https://dilwyn.qlforum.co.uk/index.html
All things QL - https://dilwyn.qlforum.co.uk/index.html
Re: Test if a directory exists
Dilwyn,
working with FMAKE_DIR or MAKE_DIR is a bit of a dangerous path. It will work in theory, but you will run into hard to fix issues in case the driver has to move files into that newly made directory:
win1_LETTER_TXT exists,
win1_LETTER_DOC exists
you try to find out whether the directory win1_letter exists
FMAKE_DIR will end you up with a directory named win1_letter and two files named txt and doc in it, and you will have a very hard time getting rid of that directory again.
Tobias
working with FMAKE_DIR or MAKE_DIR is a bit of a dangerous path. It will work in theory, but you will run into hard to fix issues in case the driver has to move files into that newly made directory:
win1_LETTER_TXT exists,
win1_LETTER_DOC exists
you try to find out whether the directory win1_letter exists
FMAKE_DIR will end you up with a directory named win1_letter and two files named txt and doc in it, and you will have a very hard time getting rid of that directory again.
Tobias
ʎɐqǝ ɯoɹɟ ǝq oʇ ƃuᴉoƃ ʇou sᴉ pɹɐoqʎǝʞ ʇxǝu ʎɯ 'ɹɐǝp ɥO
Re: Test if a directory exists
No, it does not worktofro wrote:The behavior you see has to do with the fact that opening a directory on a valid and working device may not fail on QDOS for reasons other than the file exists and is no directory (That has to do with the fact that directories were a late addition to the OS and also somewhat with the way the default drives and directories work in QDOS) - If the directory you asked for didn't open, the driver will open the directory "next up" for you, walking upwards to the root in case that fails.
What you can always do is:
- Open the directory
- Check the name of what has been opened against your desired name
Though this might still fail on aliased devices like dev_ and pth_, it is much better than nothing.Code: Select all
FUNCTION DirExists (name$) LOCAL channel, realName$ channel = FOP_DIR (name$) realName$ = FNAME$ (#channel) CLOSE #channel IF realName$ == name$ THEN RETURN 1 ENDIF RETURN 0 ENDDEF
Tobias
if name$='win2_xyzzy_' then realname$ will be always be 'xyzzy_' regardless of it's existence
FNAME$ just removes the drive from the name
-
- Font of All Knowledge
- Posts: 4039
- Joined: Mon Dec 20, 2010 11:40 am
- Location: Sunny Runcorn, Cheshire, UK
Re: Test if a directory exists
Hi,
I use the Toolkit 2 Function FTEST which tests for the existence of a file.
Since a directory is a file with type 255, then using:
PRINT FTEST("win1_dir")
would produce 0 if the directory / file exists or -7 if not exists.
Then use FTYP to test for the file type.
I use the Toolkit 2 Function FTEST which tests for the existence of a file.
Since a directory is a file with type 255, then using:
PRINT FTEST("win1_dir")
would produce 0 if the directory / file exists or -7 if not exists.
Then use FTYP to test for the file type.
Regards,
Derek
Derek
Re: Test if a directory exists
That's just the usual cr*p of how the QL filing system works of course. That and trying to sensibly handle the intricacies of the DEVs, PTHs and SUBs of this world are impractical for most QL software.tofro wrote:Dilwyn,
working with FMAKE_DIR or MAKE_DIR is a bit of a dangerous path. It will work in theory, but you will run into hard to fix issues in case the driver has to move files into that newly made directory:
win1_LETTER_TXT exists,
win1_LETTER_DOC exists
you try to find out whether the directory win1_letter exists
FMAKE_DIR will end you up with a directory named win1_letter and two files named txt and doc in it, and you will have a very hard time getting rid of that directory again.
Tobias
It depends if Andrew's requirement is to error trap a directory creation - to prevent trying to create one if already exists. In that case error trapping a MAKE_DIR or FMAKE_DIR is the best solution.
If what Andrew is trying to do is strictly just check if a diretory name exists without creating one, the FNAME$ method is better as long as you separate the drive and directory name for the test (as Andrew found).
If none of these methods fulfil what Andrew wants, he'll in all likelihood have to resort to scanning the directory tree for the directory name, though even that probably won't achieve much more than the FNAME$ method.
The other aspect of this is simply checking if the system supports directories in the first place. There are probably two methods of doing this, firstly scan the BASIC name table for a MAKE_DIR command (e.g. use EXTRAS#channel to send a list of extensions to a file, read it back and look for MAKE_DIR), or secondly use an extension such as LEVEL2 in DJToolkit to test if the system supports level 2 directories. it works by calling IOF.XINF in interrogate mode [d2.b=0 - not documented in QDOS/SMS guide] to see if the extended system information is returned or not. To study it, just search for IOF.XINF in the DJToolkit_asm sources.
--
All things QL - https://dilwyn.qlforum.co.uk/index.html
All things QL - https://dilwyn.qlforum.co.uk/index.html
Re: Test if a directory exists
Thanks Derek. Nice simple solution. Coded as a function like this:Derek_Stewart wrote:Hi,
I use the Toolkit 2 Function FTEST which tests for the existence of a file.
Since a directory is a file with type 255, then using:
PRINT FTEST("win1_dir")
would produce 0 if the directory / file exists or -7 if not exists.
Then use FTYP to test for the file type.
Code: Select all
1000 DEFine FuNction DIR_EXISTS (name$)
1010 LOCal er
1020 IF FTEST(name$) = 0 THEN
1030 IF FTYP(\name$) = 255 THEN er = 1 : ELSE er = 0 : END IF
1040 ELSE
1050 er = 0
1060 END IF
1070 RETurn er
1080 END DEFine DIR_EXISTS
--
All things QL - https://dilwyn.qlforum.co.uk/index.html
All things QL - https://dilwyn.qlforum.co.uk/index.html