|
Introduction
I have been working with the .NET framework for several weeks now and I really enjoy the API. But sometimes I miss some features I need right now, even if I expect the framework to grow and get new classes and capabilities in the forthcoming versions (like Java did).
This article doesn't try to teach something but just gives a solution to anyone who needs it. I tried to keep it simple with few lines of code.
The FileSystem class
This class includes high level functions missing in the standard System.IO namespace. The class provided here only includes a directory to directory copy function for the moment, and the purpose of this article is to fix this .NET missing feature that many VB developers (for example) are used to.
The function takes two absolute paths (source directory and destination directory) as parameters and returns a boolean equal to true when the copy succeeds. Please note that this function automatically overwrites a destination file with the same name. Of course all subdirectories are also copied recursively. using System;
using System.IO;
namespace Utility.IO{
public class FileSystem{
public static void copyDirectory(string Src,string Dst){
String[] Files;
if(Dst[Dst.Length-1]!=Path.DirectorySeparatorChar)
Dst+=Path.DirectorySeparatorChar;
if(!Directory.Exists(Dst)) Directory.CreateDirectory(Dst);
Files=Directory.GetFileSystemEntries(Src);
foreach(string Element in Files){
if(Directory.Exists(Element))
copyDirectory(Element,Dst+Path.GetFileName(Element));
else
File.Copy(Element,Dst+Path.GetFileName(Element),true);
}
}
}
}
An usage example
Here is an example of how to use the FileSystem class.
try{
copyDirectory(@"c:\MySrcDirectory",@"c:\MyDstDirectory");
}
catch(Exception Ex){
Console.Error.WriteLine(Ex.Message);
}
Conclusion
This article is just a tip targeted to beginners or newcomers who noticed this missing feature in the .NET framework. It is provided as a possible solution, but I encourage anyone to write his own function.
Happy Coding !!!
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 36 (Total in Forum: 36) (Refresh) | FirstPrevNext |
|
|
 |
|
|
You would like to check if the destination is a sub directory of the source. Otherwise you'll get an infinite loop, which will fill up your disk completely in minutes. This is one solution: (sorry I renamed the variable names to company standards)
public static void CopyDirectory(string src, string dst) { String[] files;
if (dst[dst.Length - 1] != Path.DirectorySeparatorChar) dst += Path.DirectorySeparatorChar; if (!Directory.Exists(dst)) Directory.CreateDirectory(dst);
files = Directory.GetFileSystemEntries(src);
foreach (string element in files) { if (Directory.Exists(element)) { // Sub directories if (element + Path.DirectorySeparatorChar != dst) { CopyDirectory(element, dst + Path.GetFileName(element)); } } else { // Files in directory File.Copy(element, dst + Path.GetFileName(element), true); } } }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks for the convinient func !
I applied try/catch + ret value indicates if the copy succeed. here is the updated func :
/// /// Copy directory structure recursively /// public bool copyDirectory(string Src, string Dst) { String[] Files; bool bSucess = true;
if (Dst[Dst.Length - 1] != Path.DirectorySeparatorChar) Dst += Path.DirectorySeparatorChar; if (!Directory.Exists(Dst)) Directory.CreateDirectory(Dst); Files = Directory.GetFileSystemEntries(Src); foreach (string Element in Files) { try { // Sub directories if (Directory.Exists(Element)) copyDirectory(Element, Dst + Path.GetFileName(Element)); // Files in directory
else File.Copy(Element, Dst + Path.GetFileName(Element), true); } catch (Exception) { bSucess = false; } } return bSucess; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Its such a common requirement im sure, but the .NET API doesnt support it. I googled for this functionality and hit this topic.
The code just works perfectly and I didnt even bother to understand how it was doing what it is doing. It seamlessly integrated into my program.
Thanks Sreenath
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
I am working on a project that requires me to pick folders out of a source folder, and copy them to a destination. With both examples of the code for the copy, i'm getting the content of the folders i want copied into the root of the destiation without the folder being created.
for example
the path I am passing is src = \\test\share\nc11 and dest = \\test\dest\
what I'm getting is the contents of nc11 dumped into the root of dest
I want to copy nc11 to \\test\dest\

|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
|
Hey's it's not that complex! Just use getfiles and getdirectories
// using System.IO;
private void CopyFolder( string source, string dest ) { if (!dest.EndsWith("\\")) dest += "\\";
foreach (string file in Directory.GetFiles( source )) { File.Copy(file, dest + Path.GetFileName(file), true); }
foreach (string folder in Directory.GetDirectories( source )) { string subFolder = Path.GetFileName(folder); Directory.CreateDirectory(dest + "\\" + subFolder); CopyFolder(folder, dest + "\\" + subFolder); } }
|
| Sign In·View Thread·PermaLink | 5.00/5 (2 votes) |
|
|
|
 |
|
|
Here is similar but more portable:
public static void CopyDirectory(string source, string destination, bool overwrite) { // Create the destination folder if missing. if (!Directory.Exists(destination)) Directory.CreateDirectory(destination); DirectoryInfo dirInfo = new DirectoryInfo(source); // Copy all files. foreach (FileInfo fileInfo in dirInfo.GetFiles()) fileInfo.CopyTo(Path.Combine(destination, fileInfo.Name), overwrite);
// Recursively copy all sub-directories. foreach (DirectoryInfo subDirectoryInfo in dirInfo.GetDirectories()) CopyDirectory(subDirectoryInfo.FullName, Path.Combine(destination, subDirectoryInfo.Name), overwrite); }
B.A.N.Z.A.I. ! !! !!!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Quick and easy little method to do exactly what I needed. Thanks. 
Ignore the cocky buttheads who constantly have to come in and criticize why you did it this way or how you should add this functionality to make it better.
There are only 10 types of people in this world....those that understand binary, and those that do not.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks a lot. This piece of code was no way meant to impress people. Just helpful...
R. LOPES Just programmer.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.IO; using System.Text.RegularExpressions;
namespace Project1 { public class Util { public Util() { }
/// /// Filesystem /// public class FileSystem { // Copy directory structure recursively public static void copyDirectory(string Src,string Dst, string[] SrcFilterPattern) { ArrayList FileCol = null;
if(Dst[Dst.Length-1]!=Path.DirectorySeparatorChar) Dst+=Path.DirectorySeparatorChar; if(!Directory.Exists(Dst)) Directory.CreateDirectory(Dst);
FileCol = new ArrayList(); for (int i = 0; i < SrcFilterPattern.Length; i ++) { if (SrcFilterPattern[i].CompareTo("") == 0) { FileCol.AddRange(Directory.GetFileSystemEntries(Src)); } FileCol.AddRange(Directory.GetFileSystemEntries(Src, SrcFilterPattern[i])); }
foreach(string Element in FileCol) { // Sub directories if(Directory.Exists(Element)) copyDirectory(Element,Dst+Path.GetFileName(Element), SrcFilterPattern); // Files in directory else File.Copy(Element,Dst+Path.GetFileName(Element),true); } }
// Copy directory structure recursively public static void copyDirectory(string sDir,string sDst, string fileFilterPattern) {
try {
Regex r = new Regex("(;|,)"); // Split on hyphens. string[] fileFilters = r.Split(fileFilterPattern); r = null; copyDirectory(sDir, sDst, fileFilters); } catch (System.Exception excpt) { Console.WriteLine(excpt.Message); } }
// Copy directory structure recursively public static void copyDirectory(string sDir,string sDst) { try { copyDirectory(sDir, sDst, ""); } catch (System.Exception excpt) { Console.WriteLine(excpt.Message); } }
static void Main(string[] args) { try { //copyDirectory(@"c:\temp",@"c:\temp\new", "*e.exe;*l.xml"); copyDirectory(@"c:\temp",@"c:\temp\new"); // Directory.Delete(@"c:\MySrcDirectory") to mimic a Directory.Move behaviour } catch(Exception Ex) { Console.Error.WriteLine(Ex.Message); } } }
} }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
I modified it and post the modified part here: because I tried to use it in my project, but failed(Directory.GetFileSystemEntries(Src, SrcFilterPattern[i]) got nothing at all.) public static void CopyDirectory(string Src,string Dst, string[] SrcFilterPattern) {
ArrayList FileCol = null; ArrayList DirCol = null;
if(Dst[Dst.Length-1]!=Path.DirectorySeparatorChar) Dst+=Path.DirectorySeparatorChar; if(!Directory.Exists(Dst)) Directory.CreateDirectory(Dst);
FileCol = new ArrayList(); DirCol=new ArrayList();
for (int i = 0; i < SrcFilterPattern.Length; i ++) { if (SrcFilterPattern[i].CompareTo("") == 0) { FileCol.AddRange(Directory.GetFileSystemEntries(Src)); } FileCol.AddRange(Directory.GetFiles(Src, SrcFilterPattern[i])); } DirCol.AddRange(Directory.GetDirectories(Src));
//Copy Files foreach(string Element in FileCol) { File.Copy(Element,Dst+Path.GetFileName(Element),true); }
//Copy SubDirectory foreach(string element in DirCol) { CopyDirectory(element,Dst+Path.GetFileName(element), SrcFilterPattern); } }
http://hardrock.cnblogs.com http://www.steedsoft.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
Nothing special, just use like this way(I used it in my Batch ReaderEnable project): <code>FileSystem.CopyDirectory(srcFolder,destFolder, "*.pdf");</code>
the full version class is: <code> using System; using System.Collections; using System.ComponentModel; using System.Data; using System.IO; using System.Text.RegularExpressions;
namespace com.rubypdf { /// <summary> ///Simple C#/.NET tip to copy an entire directory tree to another directory /// Function to copy a directory to another place (nothing fancy) /// orginal from http://www.codeproject.com/cs/files/copydirectoriesrecursive.asp /// Modified by Steven Lee(http://www.rubypdf.com) /// </summary> public class FileSystem { /// <summary> // Copy directory structure recursively /// </summary> /// <summary> /// Copy Directory recursively with given Filter Patterns /// </summary> /// <param name="Src">Source Dir</param> /// <param name="Dst">Dest Dir</param> /// <param name="SrcFilterPattern">String Array of Filter Pattern</param> public static void CopyDirectory(string Src,string Dst, string[] SrcFilterPattern) {
ArrayList FileCol = null; ArrayList DirCol = null;
if(Dst[Dst.Length-1]!=Path.DirectorySeparatorChar) Dst+=Path.DirectorySeparatorChar; if(!Directory.Exists(Dst)) Directory.CreateDirectory(Dst);
FileCol = new ArrayList(); DirCol=new ArrayList();
for (int i = 0; i < SrcFilterPattern.Length; i ++) { if (SrcFilterPattern[i].CompareTo("") == 0) { FileCol.AddRange(Directory.GetFileSystemEntries(Src)); } FileCol.AddRange(Directory.GetFiles(Src, SrcFilterPattern[i])); } DirCol.AddRange(Directory.GetDirectories(Src));
//Copy Files foreach(string Element in FileCol) { File.Copy(Element,Dst+Path.GetFileName(Element),true); }
//Copy SubDirectory foreach(string element in DirCol) { CopyDirectory(element,Dst+Path.GetFileName(element), SrcFilterPattern); } }
/// <summary> ///Copy Directory recursively with a given Filter Pattern /// </summary> /// <param name="sDir">Source Dir</param> /// <param name="sDst">Dest Dir</param> /// <param name="fileFilterPattern">Filter Pattern string</param> public static void CopyDirectory(string sDir,string sDst, string fileFilterPattern) { try { Regex r = new Regex("(;|,)"); // Split on hyphens. string[] fileFilters = r.Split(fileFilterPattern); r = null; CopyDirectory(sDir, sDst, fileFilters);
} catch (System.Exception excpt) { //Console.WriteLine(excpt.Message); throw excpt; } }
/// <summary> /// Copy directory structure recursively /// </summary> /// <param name="sDir">Source Dir</param> /// <param name="sDst">Dest Dir</param> public static void CopyDirectory(string sDir,string sDst) { try { CopyDirectory(sDir, sDst, ""); } catch (System.Exception excpt) { //Console.WriteLine(excpt.Message); throw excpt; } } static void Main(string[] args) { try { //copyDirectory(@"c:\temp",@"c:\temp\new", "*e.exe;*l.xml"); copyDirectory(@"c:\temp",@"c:\temp\new"); // Directory.Delete(@"c:\MySrcDirectory") to mimic a Directory.Move behaviour } catch(Exception Ex) { Console.Error.WriteLine(Ex.Message); } } } } </code>
http://www.rubypdf.com
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
using System; using System.Collections; using System.ComponentModel; using System.Data; using System.IO; using System.Text.RegularExpressions;
namespace Project1 { public class Util { public Util() { }
/// /// Filesystem /// public class FileSystem { // Copy directory structure recursively public static void copyDirectory(string Src,string Dst, string[] SrcFilterPattern) { ArrayList FileCol = null;
if(Dst[Dst.Length-1]!=Path.DirectorySeparatorChar) Dst+=Path.DirectorySeparatorChar; if(!Directory.Exists(Dst)) Directory.CreateDirectory(Dst);
FileCol = new ArrayList(); for (int i = 0; i < SrcFilterPattern.Length; i ++) { if (SrcFilterPattern[i].CompareTo("") == 0) { FileCol.AddRange(Directory.GetFileSystemEntries(Src)); } FileCol.AddRange(Directory.GetFileSystemEntries(Src, SrcFilterPattern[i])); }
foreach(string Element in FileCol) { // Sub directories if(Directory.Exists(Element)) copyDirectory(Element,Dst+Path.GetFileName(Element), SrcFilterPattern); // Files in directory else File.Copy(Element,Dst+Path.GetFileName(Element),true); } }
// Copy directory structure recursively public static void copyDirectory(string sDir,string sDst, string fileFilterPattern) {
try {
Regex r = new Regex("(;|,)"); // Split on hyphens. string[] fileFilters = r.Split(fileFilterPattern); r = null; copyDirectory(sDir, sDst, fileFilters); } catch (System.Exception excpt) { Console.WriteLine(excpt.Message); } }
// Copy directory structure recursively public static void copyDirectory(string sDir,string sDst) { try { copyDirectory(sDir, sDst, ""); } catch (System.Exception excpt) { Console.WriteLine(excpt.Message); } }
static void Main(string[] args) { try { //copyDirectory(@"c:\temp",@"c:\temp\new", "*e.exe;*l.xml"); copyDirectory(@"c:\temp",@"c:\temp\new"); // Directory.Delete(@"c:\MySrcDirectory") to mimic a Directory.Move behaviour } catch(Exception Ex) { Console.Error.WriteLine(Ex.Message); } } }
} }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
First of all its a great article and it saved me tons of time. My task was to back up a huge folder on backup server. On production server I have a backup server's mapped drive as "s". Now everytime I try to backup the directory, I get an error message "Could not find a part of the path "s:\".
Any ideas how to take care of this issue?
Thanks
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi !
I want to provide my client a utility that downloads a folder from my server and overwrite it on a pre-specified local folder without asking the user anything.
For this I am writing a windows application in C#. But I donot know how to download a whole folder(which may contain files and another folders) from server and overwrite it on a local folder.
Please help.
looking for a quick and positive response -vikas
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Public Sub CopyDir(ByVal Src As String, ByVal Dst As String) Dim Files() As String, Element As String If Microsoft.VisualBasic.Right(Dst, Dst.Length - 1) <> Path.DirectorySeparatorChar Then Dst &= Path.DirectorySeparatorChar End If If Not Directory.Exists(Dst) Then Directory.CreateDirectory(Dst) Files = Directory.GetFileSystemEntries(Src) For Each Element In Files If Directory.Exists(Element) Then CopyDir(Element, Dst & Path.GetFileName(Element)) Else File.Copy(Element, Dst & Path.GetFileName(Element), True) End If Next Element End Sub
Starlogic
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
You can change the line:
If Microsoft.VisualBasic.Right(Dst, Dst.Length - 1) <> Path.DirectorySeparatorChar Then
to:
If Not dst.EndsWith(Path.DirectorySeparatorChar) Then
Even better is the fact that, the whole if ... end if statement is not need with the following revisions:
If Directory.Exists(Element) Then CopyDir(Element, Dst & Path.GetFileName(Element)) Else File.Copy(Element, Dst & Path.GetFileName(Element), True) End If
is Changed to:
If Directory.Exists(Element) Then CopyDir(Element, Path.Combine(Dst, Path.GetFileName(Element))) Else File.Copy(Element, Path.Combine(Dst, Path.GetFileName(Element)), True) End If
The Path.Combine method will concatinate the Path.DirectorySeparatorChar onto the first argument if it is not already there!
So here is a slightly tweeked version of the whole thing:
Function CopyDir(ByVal SrcPath As String, ByVal DestPath As String)
If Not Directory.Exists(DestPath) Then Directory.CreateDirectory(DestPath) End If
Dim files() As String
files = Directory.GetFileSystemEntries(SrcPath) For Each element As String In files 'Sub directories If Directory.Exists(element) Then CopyDir(element, Path.Combine(DestPath, Path.GetFileName(element))) Else 'Files File.Copy(element, Path.Combine(DestPath, Path.GetFileName(element)), True) End If Next End Function
Hope you have fun with this !
Kevin Orcutt Software Engineer SAEC/kinetic vision www.saec-kv.com korcutt@saec-kv.com
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
First, thanks a lot for the article. I have a question about .NET framework. I really have no idea about the framework and if the question is so stupid you are free not to answer it 
Well the question is can you use the Win API in a managed .NET program. If so, why don't you use the a simple shell function to copy the directory with all of its contents. Isn't it better? :?
Mustafa Demirhan http://www.macroangel.com Sonork ID 100.9935:zoltrix
They say I'm lazy but it takes all my time
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello,
Great question because I saw someone showing this solution in a newsgroup
What about using a shell function to copy the directory ? Advantages: - Maybe the copy will be faster because you use pure native code. Problems: - Your code is not 100% .NET compliant. - Your code is not portable to another framework version (like mono on Linux) because you rely on Windows commands. - No exceptions will be raised in case of an error occurring during the shell copy. - You start a new external process.
Convinced ?
R. LOPES Just programmer.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Thanks for the answer.
GriffonRL wrote: Great question because I saw someone showing this solution in a newsgroup .
Hehe. Believe me this is my own question. I did not see it in a newsgroup I have been using my approach for years and never had a problem yet.
GriffonRL wrote: - Your code is not 100% .NET compliant. - Your code is not portable to another framework version (like mono on Linux) because you rely on Windows commands.
Yeah you are right. I never thought that because framework compatibility or OS independency is never an issue for me. I do not care about that 
GriffonRL wrote: - No exceptions will be raised in case of an error occurring during the shell copy.
Yes but you will get a return value which indicates if the operation is sucessfull or not. Isn't it good enough? Hmmm. Well in fact not. I admit that C# is a very very nice language and the one who uses C# should use it in C# way, not the old C way. So let me answer my question: NO. Using Exceptions is better.
| | | | | |