Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Creating an odd recursive directory structure 1

Status
Not open for further replies.

ilektronik

Programmer
Oct 13, 2003
7
US
Alright this is confusing to explain without drawing it out, but here we go. I am working on a team writing a web application using VB.NET. The application takes a file from one directory, and saves it into a new directory based on a directory structure logic. The piece I am working on is to create a function that figures out what the "next" directory to create is. Here is how the directory structure works: You start off with directory "00" , dump the files in that directory and the user logs off. The next user logs on, and the program should dump the files in "01" then the user logs off. This continues until we reach the directory "99". After that, the next user to log on, the program should dump the files in "01/00" . Then the next time, the program should dump the files into "01/01" , then "01/02", and so on until we reach "01/99" , and which point we move on to "02/00", then "02/01", until we reach "99/99", then the next directory to create is "01/00/00" , then "01/00/01", all the way until we reach "01/00/99", and we move on to "01/01/00". We continue this to "01/99/99", then we move on to "02/00/00", then "02/00/01", all the way to "02/99/99", and we continue this logic until we reach "99/99/99", and we move on to create "01/00/00/00", and the insanity continues.. Now if you noticed, there is no "00/01", but there is a "01/00/01", that is the only exception to the rule, the first "00" directory has no subdirectories. Ok now that I have completely confused myself in explaining this, hopefully someone can help me figure this out. Thanks!! (PS, code examples would help me since I am an ex-Java guy new to VB.NET, or VB anything for that matter)
 
I have a couple solutions, but before I explain them I have to ask, why are you using this system for saving files? i could think of several better ways to do this of the top of my head that would be a lot less trouble-prone and would not require nearly as long to figure out what the directory name should be as to save a file in that directory...the design is extremely inefficient.

you would likely be better off naming the new directories based on the date with sub-directories based on the milisecond time value of the day. Or just create a text file and store the names to the text file so you can figue out the next one based on the previous one.

Figuring out which directory to create on the fly under the guidelines used above is not only far more code than should be necessary for something like that, but it isn't pretty to the memory resources.

I'll be back shortly as I am finishing up another solution, but I have to admit I am not used to functions taking this much work.

01000111 01101111 01110100 00100000 01000011 01101111 01100110 01100110 01100101 01100101 00111111
The never-completed website:
 
Thanks for the responce. The reason I have to use this system is because I am replacing a part of a larger legacy system. There are other pieces of this system that are dependant on that file structure and I don't have any control over those. As a result, I have to work with this directory structure. I was thinking that I would try to make this more simple by working with this logic: Instead of reading the whole directory from start to finish, I'll go from finish to end. I will look for "../99", and if I find it, move on to the next directory, if i don't, look for a "../98" and so on until I find the one that the system left off at. Make sense??? Problem is I have no clue when it comes to VB so I don't know how to start with this. Thanks!
 
Thats actually the way I attacked the problem. The logic behind this stuff is a mess though. I have one that is going backwards that almost works, though I haven't had a chance to finish messing with it.

It may be easier to just evaluate all of the possible folders and just start limiting it down to one best choice based on alphabetic precedence.

Let me give it a shot real quick and I'll see what I come up with. I'll alsio see if I can't get the backwards recursive one to stop making 99/99/00 folders when it should be making 01/00.. folders

-T

01000111 01101111 01110100 00100000 01000011 01101111 01100110 01100110 01100101 01100101 00111111
The never-completed website:
 
Ok, I threw away the earlier one and re-did it a little. It depends on a little zerofill function I wrote and one external variable called MAX. I tested it with MAX = 3 simply because it was a lot easier to tell it was working right in base 3 than it was in base 10. Here is the ZeroFill function:
Code:
   '--- a zero-fill function
    Public Function ZeroFill(ByVal num As String, ByVal finalSize As Integer) As String
        If Len(num) < finalSize Then
            Return ZeroFill(&quot;0&quot; & num, finalSize)
        Else
            Return num
        End If
    End Function

And here was my last attempt at the directory structures. Note: I made an assumption that there would be no directories except for the numbered ones, if this is incorrect you will need to write a function to get an accurate count of the ## directories and replace the dnfo.GetDirectories.length with a function to loop through the directories and count them only if they are in the form ##:
Code:
Function GetLowestDir(ByVal basePath As String, Optional ByVal allow00subs As Boolean = False) As String
        Dim dnfo As New IO.DirectoryInfo(basePath)
        If Not dnfo.Exists Then Throw New Exception(&quot;The base directory does not exist or wasn't set correctly.&quot;)

        'set the low number for the next layer
        '   for example, the first layer should be set for false so we can't get 00/??
        '   later layers should be set for true so we can get 01/00/??
        Dim low_num As Integer
        If allow00subs Then
            low_num = 0
        Else
            low_num = 1
        End If

        'if base directory is less than full, then return the amount as a directory name
        If dnfo.GetDirectories.Length < MAX Then
            Return ZeroFill(dnfo.GetDirectories.Length, 2)
        Else
            'base directory is full, find best candidate from children
            Dim best_bet As String
            Dim cur_sub_best_bet As String
            Dim i As Integer

            'get the best bet for MAX - 1 (99)
            best_bet = ZeroFill(MAX - 1, 2) & &quot;\&quot; & GetLowestDir(basePath & &quot;\&quot; & ZeroFill(MAX - 1, 2), True)

            For i = MAX - 2 To low_num Step -1
                cur_sub_best_bet = ZeroFill(i, 2) & &quot;\&quot; & GetLowestDir(basePath & &quot;\&quot; & ZeroFill(i, 2), True)
                'if cur best bet does not end in 99 or 00 then it is already in use and an auto-winner
                If Strings.Right(cur_sub_best_bet, 2) <> &quot;00&quot; And Strings.Right(cur_sub_best_bet, 2) <> &quot;99&quot; Then
                    Return cur_sub_best_bet
                End If

                'if cur best bet ends in 99 then go with the previous best bet (rollover to next)
                If Strings.Right(cur_sub_best_bet, 2) = &quot;99&quot; Then
                    Return best_bet
                End If

                'at this point both must end in 00, if previous best bet is shortest, it has higher priority
                If Len(best_bet) < Len(cur_sub_best_bet) Then
                    Return best_bet
                End If

                'current must end in 00, use it as best bet and keep on going
                best_bet = cur_sub_best_bet
            Next

            'nothing else left, return our best_bet
            Return best_bet
        End If
    End Function


I had a form to use for testing, basically all I did was loop from 0 to whatever and create the directory as it was returned, then output it to a textbox so I could see it working. Beware, it will throw an exceoption if you don't give it a valid basePath on your call. Here was my sample button code:
Code:
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim i, j As Integer
        Try
            j = CInt(TextBox2.Text)
        Catch
            MsgBox(&quot;NAN&quot;)
        End Try

        Dim dnfo As IO.DirectoryInfo
        Dim next_directory as string
        For i = 1 To j
           next_directory = GetLowestDir(&quot;C:\test\&quot;)
           dnfo = New IO.DirectoryInfo(&quot;C:\test\&quot; & next_directory)
            If Not dnfo.Exists Then
                dnfo.Create()
                TextBox1.Text = dnfo.FullName & &quot; created.&quot; & vbCrLf & TextBox1.Text
            Else
                TextBox1.Text = dnfo.FullName & &quot; DUPLICATED!!!!&quot; & vbCrLf & TextBox1.Text
            End If
        Next
    End Sub
To get the sample code to work you will need a multiline textbox called textbox1, a std textbox called textbox2, and a button called button1. Put a number in textbox2 for the number of directories you want to create,m and then watch it go. I would suggest using a low number like 3, 5, 10 for MAX before going for the full 100.


Sorry for the pasting of code, I usually prefer not to do that, but in this case it was an odd enough logic problem that it was easier this way. Hopefully the commenting will help.

-T


01000111 01101111 01110100 00100000 01000011 01101111 01100110 01100110 01100101 01100101 00111111
The never-completed website:
 
perfect, it works like charm! thanks so much for you help!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top