none
Help with the File.GetFiles command RRS feed

  • Question

  • Hi I am looking for help.

    I'm using the File.GetFiles to read all files in a directory into an array for processing

    path = "M:\TotSums\"
    sum = File.GetFiles(path)

    M:\ is a mapped network drive

    I'm then processing these files and need help with 2 things.

    1- The array when using a mapped network drive is not giving me the files in file name order which it did when I was using a path local to my PC. Is there something that could be causing this and is it possibly to sort the array.

    2- The command returns a full path which i have to strip the file name out of but seems to give too many \ in the path is this a bug or by design eg. M:\\TotSums\\TOT00001.SUM

    Thanks if anyone can help me

    Chris

    Monday, May 12, 2014 9:48 PM

Answers

  • Welcome Chris,

    1] I am not sure why the file order would be different for a mapped drive.  It is certainly possible to sort an array either using an extension or writing code to do this.  If you want I can direct you to either, unless you fancy writing a subroutine for it yourself.

    2] A double \\ is usually because the \ is used as an escape character to demonstrate that the next character is special in some way, to the get the \ character without this special meaning you use \\.  Escape characters depend on the encoding (UTF-8 etc) or the language.

    For example Small Basic uses \ internally in array notation.

    Consider the following:

    data[1] = "C:\test"
    TextWindow.WriteLine(data)

    The result is the internal format describing an array:

    1=C:\\test;

    Because the array form uses \ (for multidimensional arrays), a double \\ is used to indicate that we have a \, not an escape character.

    Note that when we do:

    TextWindow.WriteLine(data[1]) we get "C:\test" - it sorts itself out.

    So, probably the \\s are OK and will work themselves out.

    If not, we may need to see some code (although if it is a Mapped Drive peculiarity it may be harder to diagnose, but I doubt it).

    Monday, May 12, 2014 10:23 PM
    Moderator
  • The easiest is bubblesort, but shellsort is faster and not too hard to code.  Here is an example sorting numbers with these - to do strings you just need some sort of text lexical comparator - which I leave to you, but I can help with.

    'Example of efficient ShellSort algorithm to sort a list, comparing with BubbleSort
    
    'Create a random 500 element array
    numVal = 500
    For i = 1 To numVal
      val[i] = Math.GetRandomNumber(numVal) 
    EndFor
    valStore = val
    
    'ShellSort it
    TextWindow.Write("ShellSort ")
    val = valStore
    start = Clock.ElapsedMilliseconds
    shellsort()
    timing = 0.001*Math.Floor(0.5+(Clock.ElapsedMilliseconds-start)) 'Nearest 1000th of a second
    TextWindow.WriteLine(timing+" sec")
    
    'BubbleSort it
    TextWindow.Write("BubbleSort ")
    val = valStore
    start = Clock.ElapsedMilliseconds
    bubblesort()
    timing = 0.001*Math.Floor(0.5+(Clock.ElapsedMilliseconds-start))
    TextWindow.WriteLine(timing+" sec")
    
    Sub shellsort
      inc = Math.Round(numVal/2)
      While inc > 0
        For i = inc To numVal
          temp = val[i]
          j = i
          while (j >= inc) and (val[j-inc] > temp)
            val[j] = val[j-inc]
            j = j - inc
          EndWhile
          val[j] = temp
        EndFor
        inc = Math.Round(inc/2.2)
      Endwhile
    Endsub
    
    Sub bubblesort
      For i = 1 To numVal
        For j = i+1 To numVal
          If (val[j] < val[i]) Then
            temp = val[i]
            val[i] = val[j]
            val[j] = temp
          EndIf
        EndFor
      EndFor
    EndSub

    Tuesday, May 13, 2014 5:31 PM
    Moderator

All replies

  • Welcome Chris,

    1] I am not sure why the file order would be different for a mapped drive.  It is certainly possible to sort an array either using an extension or writing code to do this.  If you want I can direct you to either, unless you fancy writing a subroutine for it yourself.

    2] A double \\ is usually because the \ is used as an escape character to demonstrate that the next character is special in some way, to the get the \ character without this special meaning you use \\.  Escape characters depend on the encoding (UTF-8 etc) or the language.

    For example Small Basic uses \ internally in array notation.

    Consider the following:

    data[1] = "C:\test"
    TextWindow.WriteLine(data)

    The result is the internal format describing an array:

    1=C:\\test;

    Because the array form uses \ (for multidimensional arrays), a double \\ is used to indicate that we have a \, not an escape character.

    Note that when we do:

    TextWindow.WriteLine(data[1]) we get "C:\test" - it sorts itself out.

    So, probably the \\s are OK and will work themselves out.

    If not, we may need to see some code (although if it is a Mapped Drive peculiarity it may be harder to diagnose, but I doubt it).

    Monday, May 12, 2014 10:23 PM
    Moderator
  • Thanks for the help.

    I think the best thing for me to do is to write a subroutine if you can point me to some code to get me started as it will be good a good exercise.

    Here is the full code

    GraphicsWindow.Hide()
    TextWindow.Title = "Moblie App License Expiry Checker"
    path = "M:\TotSums\"
    sum = File.GetFiles(path)

    redomonth:
    TextWindow.Clear()
    TextWindow.WriteLine("Enter The Month Number")
    month = TextWindow.ReadNumber()
    month = PlusPlusMath.Truncate(month)

    If month <1 Or month > 12 Then
      TextWindow.WriteLine("Not A Valid Month Number")
      TextWindow.WriteLine("Press Any Key To Continue")
      TextWindowPlus.PauseWithoutMessage()
      Goto redomonth
    EndIf

    redoyear:
    TextWindow.Clear()
    TextWindow.WriteLine("Do You Want The Current Year 'Y'/'N'")
    year = TextWindow.Read()
    If Text.ConvertToUpperCase(LDText.Trim(year)) = "Y" Then
      year = Clock.Year
    ElseIf Text.ConvertToUpperCase(LDText.Trim(year)) = "N" Then
      redogetyear:
      TextWindow.Clear()
      TextWindow.WriteLine("Enter The 2 Digits For The Required Year")
      year = TextWindow.ReadNumber()
      If year < 13 Or year > 100 Then
        TextWindow.WriteLine("Not A Valid Entry")
        TextWindow.WriteLine("Press Any Key To Continue")
        TextWindowPlus.PauseWithoutMessage()
        Goto redogetyear
      EndIf
      year = PlusPlusMath.Truncate(year)
      year = Text.Append("20",year)
    Else
      TextWindow.WriteLine("Not A Valid Entry")
      TextWindow.WriteLine("Press Any Key To Continue")
      TextWindowPlus.PauseWithoutMessage()
      Goto redoyear
    EndIf

    date = Text.Append(Text.Append(month,"/"),year)


    resave:
    save = Dialogs.AskForDirectory()
    If save = "" Then
      Goto resave
    EndIf

    If Text.EndsWith(save,"\") = "False" Then
      save = Text.Append(save,"\")
    EndIf

    reconf:
    TextWindow.Clear()
    TextWindow.WriteLine("Confirm You Want All Users Expiring " + date + " Saved To " + save)
    TextWindow.WriteLine("Press 'Y' To Continue, 'N' To Change  Or 'E' To Exit")
    conf = TextWindow.Read()
    If Text.ConvertToUpperCase(LDText.Trim(conf)) = "Y" Then
      TextWindow.WriteLine("Reading SUM Files")
    ElseIf Text.ConvertToUpperCase(LDText.Trim(conf)) = "N" Then
      goto redomonth
    ElseIf Text.ConvertToUpperCase(LDText.Trim(conf)) = "E" Then
      goto exit
    Else
      TextWindow.WriteLine("Not a valid entry")
      TextWindow.WriteLine("Press any key to continue")
      TextWindowPlus.PauseWithoutMessage()
      Goto reconf
    EndIf

    If PlusPlusFile.FileExists(save + "MobExp" + month + "-" + year + ".csv") = "True" Then
      PlusPlusFile.DeleteFile(save + "MobExp" + month + "-" + year + ".csv")
    EndIf

    end = SPFile.NumberOfFiles(path)
    count = 0

    For i = 50 To end
     
      a = 0
      read = 0
      usr = 0
      usrname = 0
      appno = 0
      exp = 0
      fname = sum[i]
      start = 1
      find = 1
     
    If Text.IsSubText(Text.ConvertToUpperCase(fname),".SUM") = "True" Then
      While find > 0
        find = Text.GetIndexOf(Text.GetSubTextToEnd(fname,start),"\")
        start = start + 1
      EndWhile
      fname = Text.GetSubTextToEnd(fname,start-1)
      TextWindow.WriteLine("Reading " + fname)
     
        
      If Text.IsSubText(File.ReadContents(path + fname),date) = "True" Then
        flend = LDFile.Length(path + fname)
        For a = 1 To flend
          read = File.ReadLine(path + fname,a)
            If Text.StartsWith(read,"User") = "True" Then
              usr = Text.GetSubTextToEnd(read,Text.GetIndexOf(read,"=") + 1)
                If Text.IsSubText(usr,"#") = "True" Then
                  usr = Text.GetSubText(usr,1,Text.GetIndexOf(usr,"#")-1)
                EndIf
              usr = LDText.Trim(usr)
            ElseIf Text.StartsWith(read,"License Name") = "True" Then
              usrname = Text.GetSubTextToEnd(read,Text.GetIndexOf(read,"=") + 1)
                If Text.IsSubText(usrname,"#") = "True" Then
                  usrname = Text.GetSubText(usrname,1,Text.GetIndexOf(usrname,"#")-1)
                EndIf
              usrname = LDText.Trim(usrname)
            ElseIf Text.StartsWith(read,"MOBILE NO APPS") = "True" Then
              appno = Text.GetSubTextToEnd(read,Text.GetIndexOf(read,"=") + 1)
                If Text.IsSubText(appno,"#") = "True" Then
                  appno = Text.GetSubText(appno,1,Text.GetIndexOf(appno,"#")-1)
                EndIf
              appno = LDText.Trim(appno)
            ElseIF Text.StartsWith(read,"MOBILE LICENCE EXPIRY DATE") = "True" Then
              exp = Text.GetSubTextToEnd(read,Text.GetIndexOf(read,"=") + 1)
                If Text.IsSubText(exp,"#") = "True" Then
                  exp = Text.GetSubText(exp,1,Text.GetIndexOf(exp,"#")-1)
                EndIf
              exp = LDText.Trim(exp)
            EndIf
        EndFor
          If Text.IsSubText(exp,date) = "True" Then
            File.AppendContents(save + "MobExp" + month + "-" + year + ".csv",usr + "," + usrname + "," + appno + "," + exp)
            TextWindow.WriteLine("Saving User " + usr)
            count = count + 1
          EndIf
        EndIf
      EndIf  
    EndFor


    TextWindow.WriteLine("Process Complete")
    If count < 1 Then
      TextWindow.WriteLine("There Were No Users Expiring in " + date)
      TextWindow.WriteLine("Press Any Key To Continue")
      TextWindowPlus.PauseWithoutMessage()
      Goto exit
    EndIf

    csv = PlusPlusFile.FileExists(save + "MobExp" + month + "-" + year + ".csv")
    If count > 0 And csv = "True" Then
      TextWindow.WriteLine("File MobExp" +  month + "-" + year + ".csv Saved to " + save)
      TextWindow.WriteLine("Press Any Key To Continue")
      TextWindowPlus.PauseWithoutMessage()
      Goto exit
    EndIf

    TextWindow.WriteLine("There Was A Problem Completing Process")
    TextWindow.WriteLine("Press 'R' To Retry Or Any Other Key To Exit")
    retry = TextWindow.Read()
    If Text.ConvertToUpperCase(retry) = "R" Then
      Goto redomonth
    EndIf

        
    exit:
    Program.End()

    Thanks

    Chris

    Monday, May 12, 2014 10:49 PM
  • The easiest is bubblesort, but shellsort is faster and not too hard to code.  Here is an example sorting numbers with these - to do strings you just need some sort of text lexical comparator - which I leave to you, but I can help with.

    'Example of efficient ShellSort algorithm to sort a list, comparing with BubbleSort
    
    'Create a random 500 element array
    numVal = 500
    For i = 1 To numVal
      val[i] = Math.GetRandomNumber(numVal) 
    EndFor
    valStore = val
    
    'ShellSort it
    TextWindow.Write("ShellSort ")
    val = valStore
    start = Clock.ElapsedMilliseconds
    shellsort()
    timing = 0.001*Math.Floor(0.5+(Clock.ElapsedMilliseconds-start)) 'Nearest 1000th of a second
    TextWindow.WriteLine(timing+" sec")
    
    'BubbleSort it
    TextWindow.Write("BubbleSort ")
    val = valStore
    start = Clock.ElapsedMilliseconds
    bubblesort()
    timing = 0.001*Math.Floor(0.5+(Clock.ElapsedMilliseconds-start))
    TextWindow.WriteLine(timing+" sec")
    
    Sub shellsort
      inc = Math.Round(numVal/2)
      While inc > 0
        For i = inc To numVal
          temp = val[i]
          j = i
          while (j >= inc) and (val[j-inc] > temp)
            val[j] = val[j-inc]
            j = j - inc
          EndWhile
          val[j] = temp
        EndFor
        inc = Math.Round(inc/2.2)
      Endwhile
    Endsub
    
    Sub bubblesort
      For i = 1 To numVal
        For j = i+1 To numVal
          If (val[j] < val[i]) Then
            temp = val[i]
            val[i] = val[j]
            val[j] = temp
          EndIf
        EndFor
      EndFor
    EndSub

    Tuesday, May 13, 2014 5:31 PM
    Moderator