copy entire folder

Mahares

Expert
Licensed User
Longtime User
The below code will copy the contents (files and subfolders) of a folder in your SDcard called: BarretteKinder1 to another folder in the SDcard called: BarretteKinder2

B4X:
Dim MyList As List
Dim MyFile As String
Dim i as Short

     File.MakeDir(File.DirRootExternal,"BarretteKinder2")
   MyList.Initialize      'initialize list so it is ready for a new task         
   Dim MyFile As String
   MyList=File.ListFiles(DBFilePath)
   For i=0 To MyList.Size-1
         MyFile=MyList.Get(i)
          File.Copy(File.DirRootExternal & "/BarretteKinder1",MyFile,File.DirRootExternal & "/BarretteKinder2",MyFile)
   Next
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Make sure you replace the following line:
B4X:
MyList=File.ListFiles(DBFilePath)
with:
B4X:
MyList=File.ListFiles(File.DirRootExternal & "/BarretteKinder1")
unless you are using variables for your folder path:
I tested it before I dispatched it to you and it worked for me as intended.
 
Upvote 0

cmweb

Active Member
Licensed User
Longtime User
The below code will copy the contents (files and subfolders) of a folder in your SDcard called: BarretteKinder1 to another folder in the SDcard called: BarretteKinder2

B4X:
Dim MyList As List
Dim MyFile As String
Dim i as Short

     File.MakeDir(File.DirRootExternal,"BarretteKinder2")
   MyList.Initialize      'initialize list so it is ready for a new task         
   Dim MyFile As String
   MyList=File.ListFiles(DBFilePath)
   For i=0 To MyList.Size-1
         MyFile=MyList.Get(i)
          File.Copy(File.DirRootExternal & "/BarretteKinder1",MyFile,File.DirRootExternal & "/BarretteKinder2",MyFile)
   Next
That doesn't work for me.

if MyFile is a Folder, then the file.copy will fail.

Best regards,

Carsten
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
Could you please post the code the way you had it written and point to which line in your code where the error is and explain what the error says. If I cannot help, someone in the forum will pick definitely help. had tested my code before I posted it. I am assuming you followed my code in both posts of 4/23/2012 and 4/24/2012.
 
Upvote 0

kickaha

Well-Known Member
Licensed User
Longtime User
The problem with the code posted is it cannot handle subdirectories. Below is an overview of the sub you need:

B4X:
sub Copydir (olddir, newdir)

make newdir
read all names in olddir

step through list of names:
  if the name is a file 
      copy file from olddir to newdir
  else
      call copydir (olddir+name, newdir+name)
next
end sub

If you call this once using the full path for the old dir and the new dir, then it will recursivly create all the nested dirs.

I leave it as an exercise for you to actually code it:D
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
The previous code does not handle a subfolder, only files as Kickaha stated. If you have one layer of subfolder, the below code should handle it for you:
B4X:
Dim MyList As List
Dim MyFile As String
Dim i As Int
Dim folder1, folder2  As String

   folder1= "cmweb" :folder2="cmweb2"

   File.MakeDir(File.DirRootExternal,folder1)
   File.MakeDir(File.DirRootExternal,folder2)

    MyList.Initialize        
    Dim MyFile As String
    MyList=File.ListFiles(File.DirRootExternal & "/" & folder1)
    For i=0 To MyList.Size-1
           MyFile=MyList.Get(i)
            If File.IsDirectory(File.DirRootExternal & "/" & folder1,MyFile)=True Then
                  File.MakeDir(File.DirRootExternal,folder2 & "/" & MyFile)
             Else
                        File.Copy(File.DirRootExternal & "/" & folder1,MyFile, File.DirRootExternal & "/" & folder2,MyFile)
            End If
    Next
Try it and let us know.
 
Upvote 0

cmweb

Active Member
Licensed User
Longtime User
Thanks,

I needed a solution to copy all files and sub folders and sub-sub folders... even when I don't know the sub folders yet.

And the routine should create sub folders in target directory if they don't exist yet.

I created my own solution for that now...

Best regards,

Carsten

Gesendet von meinem GT-N7000 mit Tapatalk 2
 
Upvote 0

kickaha

Well-Known Member
Licensed User
Longtime User
This sub should work - although I have not tested it
B4X:
Sub CopyDir (OldRoot, NewRoot, FolderName As String)
Dim MyList As List
Dim MyFile As String
Dim i As Int
    File.MakeDir(NewRoot,FolderName)
    MyList.Initialize
    Dim MyFile As String
    MyList=File.ListFiles(OldRoot&"/"&FolderName)
    For i=0 To MyList.Size-1
           MyFile=MyList.Get(i)
                If File.IsDirectory(OldRoot&"/"&FolderName,MyFile)=True Then
                       CopyDir(OldRoot & "/" & FolderName, NewRoot & "/" & FolderName, MyFile, )
                 Else
                         File.Copy(OldRoot&"/"&FolderName,MyFile, NewRoot&"/"&FolderName,MyFile)
                End If
    Next
End Sub

Call the sub with the path to the old folder, the path to the new folder and the folder name.

It will then call itself to create any subdirectories and copy all files.
 
Upvote 0

kickaha

Well-Known Member
Licensed User
Longtime User
It may be because there is no check for an empty directory before the loop.

Also just noticed that in the line
B4X:
CopyDir(OldRoot & "/" & FolderName, NewRoot & "/" & FolderName, MyFile, )
there is an extra "," after MyFile that should not be there.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
I took care of the comma already. That is not the problem. It is definitely in the loop when the sub calls itself.
 
Upvote 0

margret

Well-Known Member
Licensed User
Longtime User
This code does not look like it will work and as you stated it recalls it's self which is a problem. As soon as it finds a directory, it recalls it's self and clears the remaining list. So the list is now refilled with the data from the sub folder that was found. This means the other items in the first call never get copied. Also, FolderName is included as part of the path with OldRoot which should not be there because the code is using FolderName to create a new folder in the NewRoot. So when the system looks for the file it will not be found. Seems this can be quite involved if all the checks and balances are used.
 
Upvote 0

BarrySumpter

Active Member
Licensed User
Longtime User
c and c+ and c++ etc developers will know more about recursive routines than I.
C++ developers use it on a daily basis.

I use it every 2 to 5 years. And don't like it at all.

I can hear the giggles from the c++ developers now. LOL


It depends on the scope of the variables defined within the routine.

The first time the routine is called and variable A is defined
The same routine iteration calls itself as another new iteration
and defines variable A again.
Both iterations are still on the call stack and both have their own version of variable A.

I've only ever used this techniques on files and folders apps.

I don't recall using it on a b4a app as yet.
And don't know for sure if you can.
But would be very surprised it you couldn't.

hth
 
Upvote 0

kickaha

Well-Known Member
Licensed User
Longtime User
Good to see that Barry understands the principal. Anyway I have just tested the code I gave, and it works except for the empty directories as I pointed out.

Here is the tidier code:
B4X:
Sub CopyDir (OldRoot, NewRoot, OldFolderName, NewFolderName As String)

   Dim MyList As List
   Dim MyFile As String
   Dim i As Int

   File.MakeDir(NewRoot,NewFolderName)
   MyList.Initialize
   Dim MyFile As String
   MyList=File.ListFiles(OldRoot&"/"& OldFolderName)
   If MyList.Size > 0 Then
      For i=0 To MyList.Size-1
         MyFile=MyList.Get(i)
         If File.IsDirectory(OldRoot&"/"& OldFolderName,MyFile)=True Then
            CopyDir(OldRoot & "/" & OldFolderName, NewRoot & "/" & NewFolderName, MyFile, MyFile)
         Else
            File.Copy(OldRoot&"/"&OldFolderName,MyFile, NewRoot&"/"& NewFolderName,MyFile)
         End If
      Next
   End If
End Sub

and here is the code I tested it on
B4X:
File.MakeDir (File.DirDefaultExternal, "old")
File.MakeDir (File.DirDefaultExternal & "/old", "empty")
File.MakeDir (File.DirDefaultExternal & "/old", "morefiles")
File.MakeDir (File.DirDefaultExternal & "/old/morefiles", "somemore")
File.MakeDir (File.DirDefaultExternal & "/old/morefiles", "emptyagain")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old", "file1")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old", "file2")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old", "file3")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old/morefiles", "file4")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old/morefiles", "file5")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old/morefiles", "file6")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old/morefiles/somemore", "file7")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old/morefiles/somemore", "file8")
File.Copy (File.DirAssets, "cona.png", File.DirDefaultExternal & "/old/morefiles/somemore", "file9")

CopyDir (File.DirDefaultExternal, File.DirDefaultExternal, "old", "new")

cona.png was just a small file I put in assets to use in the test. As you can see it handles sub (and sub/sub) directories and also handles empty ones.

Recursion is a very powerful way of doing tasks like this.

I leave it to the reader(s) to work out how it works.
 
Upvote 0

kickaha

Well-Known Member
Licensed User
Longtime User
Hello kickaha,

We were posting at the same time so I deleted mine as it would be confusing. I'll be glad to test it! Thanks! I also look forward to learning something because kickaha has taught me so much!!:icon_clap:

:sign0100: Are you trying to embarass me? (it worked)

When you test it single step through the whole process and watch the variables, you will see that each call to CopyDir gets its own set without damaging the previous ones.

I also honestly recommend that all developers make themselves comfortable with recursion, it is one of the most powerful tools we have.
 
Upvote 0

Mahares

Expert
Licensed User
Longtime User
@Margret: I hope you or someonme else get a chance to test Kickaha code, because I tested and still get an IndexOutofBouds error.
B4X:
CopyDir (File.DirRootExternal, File.DirRootExternal, "ECA", "ECA2" )
The OldFolderName has several files and only one Subfolder. I tested with the subfolder empty. It returned the error. I inserted a file in the subfolder so it is not empty and got the error again. It is not essential that I find a solution to this.
 
Upvote 0

kickaha

Well-Known Member
Licensed User
Longtime User
@Margret: I hope you or someonme else get a chance to test Kickaha code, because I tested and still get an IndexOutofBouds error.
B4X:
CopyDir (File.DirRootExternal, File.DirRootExternal, "ECA", "ECA2" )
The OldFolderName has several files and only one Subfolder. I tested with the subfolder empty. It returned the error. I inserted a file in the subfolder so it is not empty and got the error again. It is not essential that I find a solution to this.

I have just tested this using the same settings as you and it worked.
Which line gives the error?

I can only imagine it is on
B4X:
MyFile=MyList.Get(i)

If so, what is the value of i and of OldFolderName.

Do you have any of the variables used by the sub defined as Globals?

If you zip up the program and post it on here I will have a look at it.
 
Upvote 0
Top