|
Forum List • Thread List • Refresh • New Topic • Search • Previous • Next 1 |
1. dir /s function in qbasic #535 Posted by: 2002-10-11 16:41:23 |
anyone out there that can give me pointers to where i can get a function to read all files and dirs under a given root dir like dir/s?
(QDIR doez not work.. the 'dirs' function is not working)..
/thanx |
2. qdir works very well in my pc #536 Posted by: guidance 2002-10-11 19:54:29 Last edited by: guidance 2010-11-21 20:36:10 (Total edited 1 time) |
click the icon to download.
don't know why yours doesn't, could you show us more detail? |
3. Re: qdir works very well in my pc #537 Posted by: 2002-10-11 20:37:11 |
Thanx for answering.. this is what I get..
This is the code: taken strait out of the qdir.txt
$INCLUDE "qdir.Inc" DECLARE SUB OnFileFound_ShowFileParams Dim myDir As QDir myDir.OnFileFound = OnFileFound_ShowFileParams myDir.Dirs ("c:/WINNT/*.txt", "D", "A") Print "path = ";myDir.path Print "IS QDIR WORKING?" Sleep 1000 End Sub OnFileFound_ShowFileParams Print myDir.path & myDir.FileName End sub
The result i get is this:
c:\\WINNTActive Setup Log.txt c:\\WINNTcard3d.txt c:\\WINNTEnvChecklog.txt c:\\WINNTModemDet.txt c:\\WINNTModemLog_Lucent Win Modem.txt c:\\WINNTModemLog_Standard Modem over IR link.txt c:\\WINNTModemLog_Xircom MPCI+ Modem 56 WinGlobal.txt c:\\WINNTntbtlog.txt c:\\WINNTOEWABLog.txt c:\\WINNTSchedLgU.Txt c:\\WINNTsetuplog.txt path = c: IS QDIR WORKING?
The problems i see is that the path for each hit is wrong (c:\\). Then only a fraction of files are listed.
Then this is the result after running WINNT>dir *.txt /s
. .. . . . . . . . Total Files Listed: 1554 File(s) 9?049?811 bytes
The dir command found 1554 files.
Talk to you later.
(BTW I'm running a win2000 machine)..
/A |
4. I tried example 2, works well. #538 |
In QdirTest.bas. I run win2000 also. |
5. Re: I tried example 2, works well. #539 Posted by: 2002-10-11 22:29:10 |
Hi,
So if you copy the program from my previous post what is ure result then?
Try your winnt dir..
Could you please copy some lines of tha printout in ure answer? and tell me how many *.txt files u found. (I know it will differ but you will have around 1000 - 2000 text files in ure installed winnt dir.)
Tanx.
/A |
6. Problem reproduced! #540 |
Seems QDir need to be debugged ... |
7. Re: Problem reproduced! #541 Posted by: 2002-10-12 04:08:47 |
Perfect!..
Do you have contact with the creator of QDIR?... else I'll send an email..
Tanx for checking!
/A |
8. Re: Problem reproduced! #542 Posted by: 2002-10-12 04:22:40 |
BTW... I made a post in this forum http://rapidqworld.proboards12.com/index.cgi?board=General&action=display&num=1034324306
Where I'm showin' code to do the same thing as QDIR... but the godda&mn program is crashing on me!... that would be a workaround insted of using QDIR (whatever.dirs)... but when I try to realize that in code the rapidq exe just crashes..... any ideas about that?....... . There must be a way of showing dirs under a given root dir... if not I'll just have to use some other language.
Tnx again...
/A |
9. Analysis #543 |
No, I didn't contact the qdir author.
This is a "Frequently Taken Mistake" about dir$ or findfirst/findnext API call usage in recurse. Because this function pair is non-reentrance, i.e., once we call findfirst(same with the first call of dir$) , the OS will save the environment for the following findnext(same with dir$ without parameter), but this is only one instance, we can not change to another directory and call another findfirst then jump back during that, if you jump back, the next findnext will continue with this new environment, unless you call the original findfirst again! But once you call the original findfirst again, the scan will restart from beginning, not resume from the last finding.
Let's look at the key code of QDir.inc (line number added): ------------------------------------------- SUB Dirs2 (sPathFilter AS STRING, sRejectedAttributes AS STRING, sMustAttributes AS STRING) DEFSTR pathFilter, sFileFound, sNewPathFilter, bckPath, bckFilter DEFSTR bckRejectedAttributes, bckMustAttributes, bckFilter_2 DEFINT bckHSearch IF .OnFileFound THEN 'Get The Files Only '------------------ IF INSTR(sRejectedAttributes, "D") = 0 THEN .rejectedAttributes = sRejectedAttributes & "D" ELSE .rejectedAttributes = sRejectedAttributes END IF IF INSTR(sMustAttributes, "D") THEN .mustAttributes = sMustAttributes - "D" ELSE .mustAttributes = sMustAttributes END IF pathFilter = REPLACESUBSTR$(sPathFilter, "/", "\\") sFileFound = .GetFirstFile (pathFilter) WHILE sFileFound <> "" CALLFUNC .OnFileFound sFileFound = .GetNextFile WEND bckFilter_2 = .Filter ' Get The Directories ' ------------------- .rejectedAttributes = "AHNRSTC0" ' Reject All Except Dir sFileFound = .GetFirstFile (LEFT$(pathFilter, RInstr(pathFilter, "\\")) & "*") 1 WHILE sFileFound <> "" IF INSTR(sRejectedAttributes, "D") = 0 THEN CALLFUNC .OnFileFound IF (.FileName <> "." AND .fileName <> "..") THEN sNewPathFilter = .path & .fileName & "\\" & bckfilter_2 bckPath = .path ' Saved Before Recursive Call bckFilter = .filter bckHSearch = .hSearch bckRejectedAttributes = .rejectedAttributes bckMustAttributes = .mustAttributes .rejectedAttributes = sRejectedAttributes ' The ones received by the Dirs2 .mustAttributes = sMustAttributes ' ------ RECURSIVE CALL ------------------ 2 .Dirs2 (sNewPathFilter, .rejectedAttributes, .mustAttributes) ' ------ RECURSIVE CALL ------------------ .mustAttributes = bckMustAttributes .rejectedAttributes = bckRejectedAttributes .path = bckPath ' reload after recursive call .filter = bckFilter .hSearch = bckHsearch END IF sFileFound = .GetNextFile WEND ELSE SHOWMESSAGE ("Event QDir.OnFileFound Not Defined") END IF END SUB
----------------------------------------- The algorithm is clear: Scan the files first, then directories, for every directory it found, call itself again, recursively (line 2).
In fact, once dirs2 is recursed, we can't resume to the scan where we left any more, the environment is changed (to the subdirectory in this case). Since this problem is due to the win32 api service feature, obviously will happen in any other languages.
Solution: Never leave the scan and call another findfirst in middle, no matter recursively or not. Instead, save all scanned output till no more files/subdirectories found, in one simple loop.
You can search the web, there're many VB code for this purpose, they're easy to convert to RQ.
Checked your code, also has this problem. By the way, suggest don't change the current directory, use full path instead while call dir$ to keep the code clean. Anymay, up to you.
Guidance |
10. Re: Analysis #544 Posted by: 2002-10-12 17:39:47 |
Hey.. thanx for spending ure time on this matter..
I'll kick back during the weekend... a coupple of beers in the sauna usually get the cells working... and then I'll try to produce working code next week...
/A |
11. OK I'm back... #545 Posted by: 2002-10-14 03:21:26 |
Hi there...
Now when my hangover is getting better I spent some time making code to preform what DIR /S is doing...
And here it is:
' WORKING DIR /S for rapidQ $include "rapidq.inc"
dim filelist$(6000) ' u should probably write something like "as string" but I notice no difference when not declaring datatype... dim filelist_attr(6000) as byte
Get_all_files:
' init
maxnofiles=6000 for a=0 to maxnofiles filelist_attr(a)=0 filelist$(a)="" next a currfilepek=0 workingdir=0
' end init
' do this to init a dir /s session
filelist$(currfilepek)="C:tst" 'root dir filelist_attr(currfilepek)=16 currfilepek=currfilepek+1 gosub get_dir_struct ' the filelist now contains the dir struct ' u can do something like this : 'tmp=currfilepek 'gosub get_dir_struct 'here temp points at the dir struct start 'temp=currfilepek-temp and this is the length of the struct.. 'with this info u can move things around and do more crap...
cpuhog: goto cpuhog get_dir_struct: while workingdir < currfilepek if filelist_attr(workingdir) = 16 then print "(main call) getting dir: "+filelist$(workingdir) gosub get_dir end if workingdir=workingdir+1 wend 'debug
print "im done" print currfilepek print workingdir 'end debug return
get_dir:
currentread$=DIR$(filelist$(workingdir)+"*.*",faDirectory ) while currentread$<>"" if currentread$="." or currentread$=".." then goto skipread end if filelist_attr(currfilepek)=FileRec.attr AND 16 if filelist_attr(currfilepek)=16 then currentread$=currentread$+"" end if filelist$(currfilepek)=filelist$(workingdir)+currentread$ 'debug print filerec.attr print filelist$(currfilepek) print currfilepek print filelist$(workingdir)+"*.*" 'end debug currfilepek=currfilepek+1 if currfilepek=6001 then goto cpuhog 'do something fun here like crash the computer or format c: (hehe)... end if skipread: currentread$=DIR$ wend
return
Once again thanx for explaining how DIR$ worked!..
AN COOL / TCB |
12. Suggestion #546 |
Glad to see you solved problem by yourself! There're several suggestions to exert the power of Rapid-Q:
1) use QStringList instead of array of string. 2) use sub/function instead of gosub/return. 3) use inc(var,1) or var++ instead of var=var+1
may more ... |
13. Re: dir /s function in qbasic #581 Posted by: 2002-10-21 18:47:53 |
French saying : "Better ask God than it's Saints"
Here is God reply :
It looks like that QDIRS requires $ESCAPECHAR ON :)
Examples are following
Jacques |
14. Re: dir /s function Correction Examples #582 Posted by: 2002-10-21 19:13:13 |
$ESCAPECHARS ON in only required When DIM myDIR As QDir
$ESCAPECHARS ON Dim myDir As QDir $ESCAPECHARS OFF
There must be then a PATH problem in Object Constructor ... minor bug !
Jacques
' ------- CODE TEST -------- Should work $INCLUDE "qdir.Inc"
DECLARE SUB OnFileFound_ShowFileParams
DefInt iFoundFilesCounter = 0
' $ESCAPECHARS ON only needed here >>> PATH in CONSTRUCTOR to BE CHECKED $ESCAPECHARS ON Dim myDir As QDir $ESCAPECHARS OFF
myDir.OnFileFound = OnFileFound_ShowFileParams
'Choose one of the two following lines (change "Windows" to "WINNT" for WinNt :) '------------------------------------- myDir.Dirs ("c:/Windows/*.txt", "D", "") ' N0 MUST AERGUMENTS REQUIRED 'myDir.Dirs ("c:Windows*.txt", "D", "") ' N0 MUST AERGUMENTS REQUIRED
Print "path = ";myDir.path Print "IS QDIR WORKING? "
' EXIT CONSOLE ' ------------ DefStr sExit Input "nn CR to QUIT nn", sExit Application.Terminate End
Sub OnFileFound_ShowFileParams DefStr sTmp Inc iFindFilesCounter sTmp = Str$(iFindFilesCounter) & " " & myDir.path & myDir.FileName Print sTmp End sub ' ----------- END CODE TEST ----------------- |
15. Still same problem :( #584 |
I tried above example, just the same problem as before: only the files in the root directory are listed, plus one file in a sub-sub-directory.
Don't you agree my analysis for the improper usage of findfirst/findnext ? |
16. Re: Still same problem :( #585 Posted by: 2002-10-21 23:10:46 |
It works here under WIN98 !
QDir.Dirs only listed the Root directory files here too without the $ESCAPECHARS ON/OFF correction ?
I spent a lot of time on that recursive loop :) ! Not easy to get in it ! I used QDir in few codes and it works, so your analysis must be wrong :)
It could be : - A problem in Path due to $ESCAPECHARS ? - Or a specific NT problem ? There is a note about MAX_PATH and WINNT in FindFiles API ??? But I dont think it's that ??? - Did you wait long enough after QDIR found the files in your root directory ? QDir is Slow ? While scanning in c:/Windows here, there is a ?? 10 seconds wait while scaning ?c:/windows/system... - I have not yet figured out why my correction works ? $ESCAPECHAR ON Dim myDir As QDir $ESCAPECHAR OFF :) inheritance of compilation directive by a class ... :) in CONSTRUCTOR QDir.Inc is in $ESCAPECHARS ON mode from first to the last line ! Last line being $ESCAPECHAR$ OFF
But it's was work time here ! I'll look forward !
Jacques |
17. Re: Still same problem :( #617 Posted by: 2002-10-28 03:10:54 |
Hello,
I spent sometime on that QIRBUG this windy Sunday
It appears that $ESCAPECHARS scope is rather unpredictable when using EXTENDED OBJECTS, the sequential compilation of rapidQ seems to be broken when using EXTENDED OBJECTS ??????
Here is a bug test code
' --- code start -------- ' ------------------------------------- ''''''''''''''$ESCAPECHARS ON $TYPECHECK ON ' Type QBug Extends QObject PUBLIC: Function EscapePath (inPath As String) As String DefStr sInPath, sOutPath, sInPath = inPath ' ---------- Test 1 ---------- UNCOMMENT/COMMENT TEST 1/2 '$ESCAPECHARS ON ' sOutPath = ReplaceSubstr$(sInPath, "/", "\\") '$ESCAPECHARS OFF ' ------------------------------ ' ----------- Test 2 ---------- sOutPath = ReplaceSubstr$(sInPath, "/", "") ' ------------------------------ Result = sOutPath End Function End Type ' '''''''''''$ESCAPECHARS OFF $TYPECHECK OFF ' -------------------------------------
' "RUNNING CODE" ' -------------- Const RQCR = Chr$(10) $ESCAPECHARS ON ' UNCOMMENT/COMMENT This line with TEST1/2 $TYPECHECK ON $INCLUDE "RAPIDQ.INC"
Dim myBug As QBug
Print myBug.EscapePath ("c:/dir1/dir2/filename")
' EXIT CONSOLE ' ------------ DefStr sExit Print (RQCR & RQCR) Input " CR to QUIT " , sExit Print (RQCR & RQCR) Application.Terminate End ' ----------- Code End ---------
The best turn around for QDIR is to do this :
$ESCAPECHARS ON Dim myDir As QDir $ESCAPECHAR$ OFF
If you dont use $ESCAPECHARS ON in your code.
Jacques |
18. QDIR update Version 003 #619 Posted by: 2002-10-29 07:58:02 |
Hello,
A new version of QDIR available at :
http://users.teledisnet.be/web/jph01696/qdirbeta003.zip
Works too when $ESCAPECHARS is OFF now :)
All references to $ESCAPECHARS have been removed from QDIR_003
$ESCAPECHARS bug Demo : http://users.teledisnet.be/web/jph01696/bugescapechardemo.zip
Jacques |
19. Re: QDIR update Version 003 #621 Posted by: 2002-10-29 15:08:32 |
thanx.. I'll incorperate qdir in my program.. |
20. Re: QDIR update Version 003 #622 Posted by: guidance 2002-10-29 18:25:50 Last edited by: guidance 2010-11-21 20:41:46 (Total edited 2 times) |
Thanks!
By the way, the Rapid-Q area is an alternative place to release/announce your QDIR contribution too, welcome!
Guidance |
Forum List • Thread List • Refresh • New Topic • Search • Previous • Next 1 |