Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Sample program using the new _Files$ function
#1
Well about time! I have been waiting for a function similar to the one in BC7 called Dir$() for years! Big Grin 

This sample program searches for files with *,?,^ matching. Also recurses directories and subdirectories and their files.

Can also write output to a file and stores directory and filename arrays.

Also compatible with Win/Linux/OSX platforms.

Erik.

@a740g: Thanks for the time and effort writing a _Files$ function.

  v2.0a:
    Adds dirspec match and restart.
    Adds shellsort for dirs and files.
  v2.1a:
    Adds statusline and ctrl-break trap.
    Adds filename search to titlebar.
  v2.2a:
    Adds Case-Sensitive selection.
  v3.0a:
    Fixes print position output.
    Fixes exit loop in prompt output file.

Now 656 lines.

Things I like about _files$ is the improvement over dir$ when matching directories appended with slash and lan capability when specified as \\server\share\

[Image: filedir.jpg]

A simple breakdown of the Files$ function:

Code: (Select All)
DefLng A-Z
Rem $Dynamic

Dim Shared Directories(1) As String
Dim Shared Filenames(1) As String
Dim Shared MaxDirs As Long
Dim Shared MaxFiles As Long

Dim Directory As String
_ScreenMove _Middle
Color 15
Print "Enter dirspec";: Input Directory
If Directory = "" Then Directory = _CWD$
If _DirExists(Directory) Then
   If Right$(Directory, 1) <> "\" Then Directory = Directory + "\"
   PrintDirectory Directory
End If
Print "Dirs"; MaxDirs; "Files"; MaxFiles
Print "Dirlist:"
Count = 0
For L = 1 To MaxDirs
   Color 15
   Print Directories(L)
   Count = Count + 1
   If Count >= 24 Then
      Color 14
      Print "-more-";
      Do
         _Limit 50
         X$ = InKey$
         If LCase$(X$) = "y" Then Print: Count = 0: Exit Do
         If LCase$(X$) = "n" Then Print: Count = 0: Exit For
      Loop
   End If
Next
If Count Then
   Color 14
   Print "-more-";
   Do
      _Limit 50
      If Len(InKey$) Then Print: Exit Do
   Loop
End If
Color 15
Count = 0
Print "Filelist:"
For L = 1 To MaxFiles
   Color 15
   Print Filenames(L)
   Count = Count + 1
   If Count >= 24 Then
      Color 14
      Print "-more-";
      Do
         _Limit 50
         X$ = InKey$
         If LCase$(X$) = "y" Then Print: Count = 0: Exit Do
         If LCase$(X$) = "n" Then Print: Count = 0: Exit For
      Loop
   End If
Next
If Count Then
   Color 14
   Print "-more-";
   Do
      _Limit 50
      If Len(InKey$) Then Print: Exit Do
   Loop
End If
Color 7
End

Sub PrintDirectory (Directory As String)
   Dim I As _Unsigned Long
   Dim N As _Unsigned Long
   Dim VarX As String
   Dim Entry(0 To 0) As String
   Dim E As String
   ' start search
   E = _Files$(Directory)
   Do
      Entry(N) = E
      N = N + 1
      If N > UBound(Entry) Then
         ReDim _Preserve Entry(0 To N) As String
      End If
      ' continue search
      E = _Files$
   Loop While Len(E) > 0
   VarX$ = Directory
   GoSub StoreFile
   While I < N
      If Entry(I) <> ".\" And Entry(I) <> "..\" Then
         If Right$(Entry(I), 1) = "\" Then
            PrintDirectory Directory + Entry(I)
         Else
            VarX$ = Directory + Entry(I)
            GoSub StoreFile
         End If
      End If
      I = I + 1
   Wend
   Exit Sub
   StoreFile:
   If Right$(VarX$, 1) = "\" Then
      MaxDirs = MaxDirs + 1
      ReDim _Preserve Directories(MaxDirs) As String
      Directories(MaxDirs) = VarX$
   Else
      MaxFiles = MaxFiles + 1
      ReDim _Preserve Filenames(MaxFiles) As String
      Filenames(MaxFiles) = VarX$
   End If
   Return
End Sub


Attached Files
.zip   FILEDIR3.ZIP (Size: 4.85 KB / Downloads: 9)
Reply
#2
(01-20-2024, 04:29 AM)eoredson Wrote: Well about time! I have been waiting for a function similar to the one in BC7 called Dir$() for years! Big Grin 

This sample program searches for files with *,?,^ matching. Also recurses directories and subdirectories and their files.

Can also write output to a file and stores directory and filename arrays.

Also compatible with Win/Linux/OSX platforms.

Erik.

@a740g: Thanks for the time and effort writing a _Files$ function.
You are welcome! Smile
Reply
#3
(01-20-2024, 09:19 PM)a740g Wrote:
(01-20-2024, 04:29 AM)eoredson Wrote: Well about time! I have been waiting for a function similar to the one in BC7 called Dir$() for years! Big Grin 

This sample program searches for files with *,?,^ matching. Also recurses directories and subdirectories and their files.

Can also write output to a file and stores directory and filename arrays.

Also compatible with Win/Linux/OSX platforms.

Erik.

@a740g: Thanks for the time and effort writing a _Files$ function.
You are welcome! Smile
Now all you have left to do is write code for UDT arrays! Heh heh heh.

Erik.
Reply
#4
This code does not work concerning UDT elements:

Code: (Select All)
Type Struct1
  A As _Bit
  B As _Byte
End Type
Dim Struct2 As Struct1
Struct2.A = 1
Struct2.B = -1
Print Struct2.B
Cannot resolve bit-length variables inside user defined type.
Reply
#5
(01-26-2024, 05:22 AM)eoredson Wrote: This code does not work concerning UDT elements:

Code: (Select All)
Type Struct1
  A As _Bit
  B As _Byte
End Type
Dim Struct2 As Struct1
Struct2.A = 1
Struct2.B = -1
Print Struct2.B
Cannot resolve bit-length variables inside user defined type.
_BIT is not currently supported in User Defined TYPEs

As seen here in the Wiki:

https://qb64phoenix.com/qb64wiki/index.php/TYPE
There are two ways to write error-free programs; only the third one works.
QB64 Tutorial
Reply
#6
What is really needed is UDT arrays such as:

Code: (Select All)
Type Struct1
  A(1 to 10) As Integer
  B(1 to 10) As Single
End Type

Type Struct2
  T(1 to 10) As Struct1
End Type

Dim StructX As Struct1
Dim StructY As Struct2

StructX.A(10) = -1
Print StructX.A(10)

StructY.T(10).A(10) = -1
Print StructY.T(10).A(10)
End
Reply
#7
(01-26-2024, 05:34 AM)TerryRitchie Wrote:
(01-26-2024, 05:22 AM)eoredson Wrote: This code does not work concerning UDT elements:

Code: (Select All)
Type Struct1
  A As _Bit
  B As _Byte
End Type
Dim Struct2 As Struct1
Struct2.A = 1
Struct2.B = -1
Print Struct2.B
Cannot resolve bit-length variables inside user defined type.
_BIT is not currently supported in User Defined TYPEs

As seen here in the Wiki:

https://qb64phoenix.com/qb64wiki/index.php/TYPE
Yes, however: A As _Bit does not produce an error but Struct2.A = 1 does!?

I would also like: Dim s As _Byte * 4
Reply
#8
https://qb64phoenix.com/qb64wiki/index.php/BIT

Quote:_BIT is not supported in User Defined TYPES. Use a _BYTE and assign up to 8 bit values as shown below.

Why would you even want a _BIT in an User Defined Type?

TYPE foo
A As _Bit
B As _Byte
END TYPE

That bit is going to take a whole byte to be stored, as a byte is the smallest piece of memory in a computer. Write out how you'd expect 3 entries of that to be written to a file. Are you suggesting that that type is now regarded as 9-bits? The first record is from bit 1 to 9, second record from bit 10 to 18, third record from bit 19 to 27, with blank space at bits 28 to 32? 3 data entries using 4-bytes of information?

Man, the overhead on that is going to be INSANE!! Bit packing across data fields! You'll have to calculate start-bit position, turn it into a corresponding byte. (For record two, the starting bit is 10, so that's in byte 2.) Then you read 2 bytes. (byte 2 and 3 of the data record) Then you shift it left so that you position the first bit in the A position for you bit type. Then you truncate anything beyond the 8 bits necessary for the B position. Then you return that value....

*Blink* *Blink*

Is it doable? SURE IT IS!! (You'd have to write your own bit compression routines to do it, however, as it's not something the language supports natively.)

Is it going to use oodles of CPU power, take forever and ever to execute, and cause a massive bottleneck in any programming loops? YEP! INDUBIDABLY!!

What's going to happen would be the same that happens with any variable of _BIT type:

1) That _BIT is going to be stored as a _BYTE.
2) That _BYTE is going to be stored as a _BYTE.
3) Each data field is going to be 2-bytes in size. The only difference is once you read the first byte, it'll perform AND 1 to only keep the bit value.

So your UDT is going to use 6-bytes --- no bit packing -- to store that information, and then it's going to work math on the value which you defined as a _BIT so that it *only* returns one bit out of that byte. Your 3 data records are going to be 6-bytes in size....

...and if they're going to be 2-bytes in size each, anyway, WHY WOULD YOU WANT TO SLOW IT DOWN WITH EXTRA, UNNECESSARY MATHS??



It's like saying:

Type foo
Dim A As _Person
Dim B As _Bus
End Type

Now, you want to drive down the road to get from point A to point B. That _Person can't just run out on the interstate and yell, "Booden!! Booden!!" and motor down the highway. He's got to climb up into a Bus himself, before he's allowed to travel on those roads.

People can't booden booden down the interstate. Bits can't travel through memory. Only Buses and Bytes do that.
Reply
#9
So, Steve, I've been using _BYTEs for my boolean TRUE/FALSE flags thinking that they take up less memory than an INTEGER. Is that a FALSE notion?
Reply
#10
I think integers and bytes are the same size on the backend, if I'm not mistaken.
Tread on those who tread on you

Reply




Users browsing this thread: 1 Guest(s)