|
Here is similar but more portable:
public static void CopyDirectory(string source, string destination, bool overwrite)
{
if (!Directory.Exists(destination))
Directory.CreateDirectory(destination);
DirectoryInfo dirInfo = new DirectoryInfo(source);
foreach (FileInfo fileInfo in dirInfo.GetFiles())
fileInfo.CopyTo(Path.Combine(destination, fileInfo.Name), overwrite);
foreach (DirectoryInfo subDirectoryInfo in dirInfo.GetDirectories())
CopyDirectory(subDirectoryInfo.FullName, Path.Combine(destination, subDirectoryInfo.Name), overwrite);
}
B.A.N.Z.A.I. ! !! !!!
|
|
|
|
|
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.
|
|
|
|
|
Thanks a lot.
This piece of code was no way meant to impress people. Just helpful...
R. LOPES
Just programmer.
|
|
|
|
|
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);
}
}
}
}
}
|
|
|
|
|
Good addition indeed.
R. LOPES
Just programmer.
|
|
|
|
|
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
|
|
|
|
|
can you give me the example that uses the class file you have modified?
thanks
tirumal
|
|
|
|
|
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
|
|
|
|
|
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);
}
}
}
}
}
|
|
|
|
|
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
|
|
|
|
|
|
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
|
|
|
|
|
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
|
|
|
|
|
You can change the line:
If Microsoft.VisualBasic.Right(Dst, Dst.Length - 1) <> Path.DirectorySeparatorChar Then<br />
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:
<br />
If Directory.Exists(Element) Then<br />
CopyDir(Element, Dst & Path.GetFileName(Element))<br />
Else<br />
File.Copy(Element, Dst & Path.GetFileName(Element), True)<br />
End If<br />
is Changed to:
<br />
If Directory.Exists(Element) Then<br />
CopyDir(Element, Path.Combine(Dst, Path.GetFileName(Element)))<br />
Else<br />
File.Copy(Element, Path.Combine(Dst, Path.GetFileName(Element)), True)<br />
End If<br />
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:
<br />
Function CopyDir(ByVal SrcPath As String, ByVal DestPath As String)<br />
<br />
If Not Directory.Exists(DestPath) Then<br />
Directory.CreateDirectory(DestPath)<br />
End If<br />
<br />
Dim files() As String<br />
<br />
files = Directory.GetFileSystemEntries(SrcPath)<br />
For Each element As String In files<br />
'Sub directories <br />
If Directory.Exists(element) Then<br />
CopyDir(element, Path.Combine(DestPath, Path.GetFileName(element)))<br />
Else 'Files<br />
File.Copy(element, Path.Combine(DestPath, Path.GetFileName(element)), True)<br />
End If<br />
Next<br />
End Function<br />
Hope you have fun with this !
Kevin Orcutt
Software Engineer
SAEC/kinetic vision
www.saec-kv.com
korcutt@saec-kv.com
|
|
|
|
|
do u know how to determine drive types using C#. Just like what GetDriveTyes are doing in windows SDK.
|
|
|
|
|
you can use driveinfo instead
|
|
|
|
|
try this
DriveInfo[] drives = DriveInfo.GetDrives();
foreach (DriveInfo drive in drives)
{
Console.WriteLine("Drive: {0}", drive.Name);
Console.WriteLine("Type: {0}", drive.DriveType); // this is your target
}
Regards,
A.Ragab
|
|
|
|
|
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
<nobr>They say I'm lazy but it takes all my time
|
|
|
|
|
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.
|
|
|
|
|
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 :P
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.
Hey, but you can check the value and raise your own exception
GriffonRL wrote:
- You start a new external process.
I really didn't know that. Are you sure about that?
PS: One nice thing with using Shell functions is that you can put the files directly to the Recycle Bin (instead of deleting them).
Lastly, let me ask you another question: How is your experience with .NET till now? Is it really more productive than VC++? I love C#; but I do not like the .NET Framework it self and I hate the CLR (or whatever it is, the intermediate compiler thing - the code is not compiled into the native code).
I hope someday, Microsoft will come up with a native C# compiler with a new version of MFC (I dont want any language interoperability. All I want is to use a language like C# not C++ ).
Mustafa Demirhan
http://www.macroangel.com
Sonork ID 100.9935:zoltrix
<nobr>They say I'm lazy but it takes all my time
|
|
|
|
|
Hello,
Yes I agree that C# is a very nice language and we will soon get new important features like generics .
I have a long experience with Java and C++, and I found C# very easy to learn with that background.
I first played a little bit with ASP.NET 1 year ago but stopped for several months. I resumed my experiments a few months ago with the Visual Studio .NET release, and now we use .NET to build our business applications.
I really think this language is more productive than C++, or at least less harmful than C++. Writing bad C++ code is easier than writing bad C# code. Of course C# still miss some features but is is coming soon.
I have nothing against the .NET framework and it is full of helpful classes that speed up the development process a lot. I programmed a lot with Java and really enjoyed the Java APIs. The new .NET framework makes more sense than the system DLL we used to for Windows programming. MFC for example has a heavy heritage behind it.
The beauty of .NET if you develop only for Windows platforms, is that you can still write critical functions in a native C++ DLL and call them from your skeleton program written in C#/.NET.
Because the C# language has been submitted to the ECMA and specifications are available, anybody could write a C# compiler to native code. Or maybe someone will create a program to convert all CLR code into native code: some solutions exist for Java where .class files are converted into Windows .EXE.
So wait and see,
R. LOPES
Just programmer.
|
|
|
|
|
you mentioned that c# will be getting generics, what are those?
|
|
|
|
|
|
First off, it's a great article that points out another thing that's wrong with the FCL. Now...if you don't mind, I'd like to critique it a bit.
First off, there's no reason to return bool. A better way to do it would be to use straight Exceptions. To put it in Rama's words: "It's not the way of the Framework." The System.IO.File.Copy() method is marked as public static void Copy() , so what you should do is make this return void and stick to using Exceptions.
Another thing, when you say:
catch(Exception Ex)
{
Console.Error.WriteLine(Ex.Message);
Success=false;
}
That's wrong. Your code, as part of a class library, should never visually display information...and that includes writing to the console. You should let the consumer handle that. Jeffrey Richter points this out in his book Applied Microsoft .NET Framework Programming, the DataGrid displays a MessageBox when there is an error in setting the CurrentCell property. I know that as an app-writer, I would hate to have a component or utility that I was using display visual information to the user without my consent.
Oh, and you don't need a constructor in your class unless there are other methods that are not marked as static . So I would remove that because really, this class should never be instantiated.
That being said, it's a great implementation for something that should be in the Framework.
You will now find yourself in a wonderous, magical place, filled with talking gnomes, mythical squirrels, and, almost as an afterthought, your bookmarks
-Shog9 teaching Mel Feik how to bookmark
I don't know whether it's just the light but I swear the database server gives me dirty looks everytime I wander past.
-Chris Maunder
|
|
|
|
|
Hello,
Thank you for your nice post !
I totally agree with all your remarks .
I have to explain why I have this Console.Error.WriteLine(Ex.Message) stuff and a boolean just after.
That's because I catch the exceptions in the static function, the calling method never gets the info. So that's why I return a boolean.
But why I am catching the exception in the function ? Just because this function is coming from my framework and it is the way I wanted it. Actually, I redirect all Console.Error.WriteLine to a XML error file (see http://www.codeproject.com/csharp/XML_Error_Log.asp[^]) and it is important the message comes from the function. But you can tell me I can retrow the exception just after I logged it and you are right: it will be the best solution to be "in the way of the framework".
I think I will update the article, reduce the code size again and try/catch the exceptions in the usage example.
And yes, I can remove this nasty useless constructor even if it doesn't create any trouble . I use a template to build all my classes and I always have one.
Thank you again for your remarks. I will help me clean the code.
R. LOPES
Just programmer.
|
|
|
|
|