I can do this so simply with files, like so:
public static void MoveAllFilesFromDesktopToJDrive()
{
DirectoryInfo di = new DirectoryInfo(#"C:\Users\Tafe\Desktop\");
DirectoryInfo Jdrive = new DirectoryInfo(#"J:\");
foreach (FileInfo fi in di.GetFiles())
{
if (Path.GetFileName(fi.FullName) != "desktop.ini")
{
fi.MoveTo(Jdrive.FullName + Path.GetFileName(fi.FullName));
}
}
}
But trying the same operation on directories tells me I can't move directories accross volumes. OK then, so this is what I've tried:
public static void MoveAllDirsFromDeskTopToJDrive()
{
DirectoryInfo di = new DirectoryInfo(#"C:\Users\Tafe\Desktop\");
DirectoryInfo Jdrive = new DirectoryInfo(#"J:\");
foreach (DirectoryInfo dirs in di.GetDirectories())
{
Directory.CreateDirectory(Jdrive + Path.GetFileName(dirs.FullName));
}
}
This copies the names of the files, but not the contents, I would just move the contents like I did with my MoveAllFilesFromDesktopToJDrive() method, but the directories contain subdirectories and subdirectories and such, so I can't figure it out. I know a TINY bit about recursion, but not enough to even attempt this. Also, It can't be that hard can it? There has to be something better in the API to facilitate this? If not, any help to complete this method MoveAllFilesFromDesktopToJDrive() would be a lifesaver!
Try looping this somewhere within your code:
string fileName = "test.txt";
string sourcePath = #"C:\Users\Public\TestFolder";
string targetPath = #"C:\Users\Public\TestFolder\SubDir";
// Use Path class to manipulate file and directory paths.
string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
string destFile = System.IO.Path.Combine(targetPath, fileName);
// To copy a folder's contents to a new location:
// Create a new target folder, if necessary.
if (!System.IO.Directory.Exists(targetPath))
{
System.IO.Directory.CreateDirectory(targetPath);
}
System.IO.File.Copy(sourceFile, destFile, true);
For more details visit this link : http://msdn.microsoft.com/en-us/library/cc148994.aspx
Related
What is the best way to move directory with all its contents(files or folders) in C#?
I used the following codes, but it throws The Directory is not empty exception :
Microsoft.VisualBasic.FileIO.FileSystem.MoveDirectory(sourceFullName, destFullName, true);
Directory.Move(sourceFullName, destFullName); //Added in edit
MSDN example enough for this.
string sourceDirectory = #"C:\source";
string destinationDirectory = #"C:\destination";
try
{
Directory.Move(sourceDirectory, destinationDirectory);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Even, as MSDN says, you will get an IOException if:
An attempt was made to move a directory to a different volume.
destDirName already exists.
The sourceDirName and destDirName parameters refer to the same file
or directory.
So, verify whether any of above is causing for error.
Also, you might consider deleting existing directory before moving. This would avoid raising error if error is due to 2nd option mention above.
if(Directory.Exists(destinationDirectory) == false)
{
Directory.Move(sourceDirectory, destinationDirectory);
}
else
{
//Delete existing directory
//But make sure you really want to delete.
}
You can try this
DirectoryInfo dir = new DirectoryInfo(source);
dir.MoveTo(newLocation);
Use System.Io.
string source = #"c:\new";
string dest = #"c:\newnew";
Directory.Move(source, dest);
here is a example ...you should move all files before move directory
string fileName = "test.txt";
string sourcePath = #"C:\Users\Public\TestFolder";
string targetPath = #"C:\Users\Public\TestFolder\SubDir";
// Use Path class to manipulate file and directory paths.
string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
string destFile = System.IO.Path.Combine(targetPath, fileName);
// To copy a folder's contents to a new location:
// Create a new target folder, if necessary.
if (!System.IO.Directory.Exists(targetPath))
{
System.IO.Directory.CreateDirectory(targetPath);
}
// To copy a file to another location and
// overwrite the destination file if it already exists.
System.IO.File.Copy(sourceFile, destFile, true);
// To copy all the files in one directory to another directory.
// Get the files in the source folder. (To recursively iterate through
// all subfolders under the current directory, see
// "How to: Iterate Through a Directory Tree.")
// Note: Check for target path was performed previously
// in this code example.
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
fileName = System.IO.Path.GetFileName(s);
destFile = System.IO.Path.Combine(targetPath, fileName);
System.IO.File.Copy(s, destFile, true);
}
}
else
{
Console.WriteLine("Source path does not exist!");
}
Use this would help you:
string sourceDir = #"c:\test";
string destinationDir = #"c:\test1";
try
{
// Ensure the source directory exists
if (Directory.Exists(sourceDir) == true )
{
// Ensure the destination directory doesn't already exist
if (Directory.Exists(destinationDir) == false)
{
// Perform the move
Directory.Move(sourceDir, destinationDir);
}
else
{
// Could provide the user the option to delete the existing directory
// before moving the source directory
}
}
else
{
// Do something about the source directory not existing
}
}
catch (Exception)
{
// TODO: Handle the exception that has been thrown
}
What about the following solution, it works well :
public static void DeleteDirectory(string targetDir)
{
string[] files = Directory.GetFiles(targetDir, "*", SearchOption.AllDirectories);
foreach (string file in files)
File.Delete(file);
new Microsoft.VisualBasic.Devices.Computer().FileSystem.DeleteDirectory(targetDir, DeleteDirectoryOption.DeleteAllContents);
}
public static void MoveDirectory(string source, string dest)
{
new Microsoft.VisualBasic.Devices.Computer().FileSystem.CopyDirectory(source, dest, true);
DeleteDirectory(source);
}
What is the best way to move directory with all its contents(files or folders) in C#?
I used the following codes, but it throws The Directory is not empty exception :
Microsoft.VisualBasic.FileIO.FileSystem.MoveDirectory(sourceFullName, destFullName, true);
Directory.Move(sourceFullName, destFullName); //Added in edit
MSDN example enough for this.
string sourceDirectory = #"C:\source";
string destinationDirectory = #"C:\destination";
try
{
Directory.Move(sourceDirectory, destinationDirectory);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Even, as MSDN says, you will get an IOException if:
An attempt was made to move a directory to a different volume.
destDirName already exists.
The sourceDirName and destDirName parameters refer to the same file
or directory.
So, verify whether any of above is causing for error.
Also, you might consider deleting existing directory before moving. This would avoid raising error if error is due to 2nd option mention above.
if(Directory.Exists(destinationDirectory) == false)
{
Directory.Move(sourceDirectory, destinationDirectory);
}
else
{
//Delete existing directory
//But make sure you really want to delete.
}
You can try this
DirectoryInfo dir = new DirectoryInfo(source);
dir.MoveTo(newLocation);
Use System.Io.
string source = #"c:\new";
string dest = #"c:\newnew";
Directory.Move(source, dest);
here is a example ...you should move all files before move directory
string fileName = "test.txt";
string sourcePath = #"C:\Users\Public\TestFolder";
string targetPath = #"C:\Users\Public\TestFolder\SubDir";
// Use Path class to manipulate file and directory paths.
string sourceFile = System.IO.Path.Combine(sourcePath, fileName);
string destFile = System.IO.Path.Combine(targetPath, fileName);
// To copy a folder's contents to a new location:
// Create a new target folder, if necessary.
if (!System.IO.Directory.Exists(targetPath))
{
System.IO.Directory.CreateDirectory(targetPath);
}
// To copy a file to another location and
// overwrite the destination file if it already exists.
System.IO.File.Copy(sourceFile, destFile, true);
// To copy all the files in one directory to another directory.
// Get the files in the source folder. (To recursively iterate through
// all subfolders under the current directory, see
// "How to: Iterate Through a Directory Tree.")
// Note: Check for target path was performed previously
// in this code example.
if (System.IO.Directory.Exists(sourcePath))
{
string[] files = System.IO.Directory.GetFiles(sourcePath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
fileName = System.IO.Path.GetFileName(s);
destFile = System.IO.Path.Combine(targetPath, fileName);
System.IO.File.Copy(s, destFile, true);
}
}
else
{
Console.WriteLine("Source path does not exist!");
}
Use this would help you:
string sourceDir = #"c:\test";
string destinationDir = #"c:\test1";
try
{
// Ensure the source directory exists
if (Directory.Exists(sourceDir) == true )
{
// Ensure the destination directory doesn't already exist
if (Directory.Exists(destinationDir) == false)
{
// Perform the move
Directory.Move(sourceDir, destinationDir);
}
else
{
// Could provide the user the option to delete the existing directory
// before moving the source directory
}
}
else
{
// Do something about the source directory not existing
}
}
catch (Exception)
{
// TODO: Handle the exception that has been thrown
}
What about the following solution, it works well :
public static void DeleteDirectory(string targetDir)
{
string[] files = Directory.GetFiles(targetDir, "*", SearchOption.AllDirectories);
foreach (string file in files)
File.Delete(file);
new Microsoft.VisualBasic.Devices.Computer().FileSystem.DeleteDirectory(targetDir, DeleteDirectoryOption.DeleteAllContents);
}
public static void MoveDirectory(string source, string dest)
{
new Microsoft.VisualBasic.Devices.Computer().FileSystem.CopyDirectory(source, dest, true);
DeleteDirectory(source);
}
I'm trying this function, which copies all files from a folder, and relative subfolders with files to another location:
using System.IO;
private static bool CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting)
{
bool ret = true;
try
{
SourcePath = SourcePath.EndsWith(#"\") ? SourcePath : SourcePath + #"\";
DestinationPath = DestinationPath.EndsWith(#"\") ? DestinationPath : DestinationPath + #"\";
if (Directory.Exists(SourcePath))
{
if (Directory.Exists(DestinationPath) == false)
Directory.CreateDirectory(DestinationPath);
foreach (string fls in Directory.GetFiles(SourcePath))
{
FileInfo flinfo = new FileInfo(fls);
flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting);
}
foreach (string drs in Directory.GetDirectories(SourcePath))
{
DirectoryInfo drinfo = new DirectoryInfo(drs);
if (CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting) == false || drs.Substring(drs.Length-8) == "archive")
ret = false;
}
}
else
{
ret = false;
}
}
catch (Exception e)
{
Console.WriteLine("{0} {1} {2}", e.Message, Environment.NewLine + Environment.NewLine, e.StackTrace);
ret = false;
}
return ret;
}
It works good until you have to copy the folder into another location, but when you have to create a folder in itself (In my example I'm doing a subfolder called "archive" to keep track of the last folder files changes) it goes in infinite loops, because it keeps rescanning itself in the Directory.GetDirectories foreach loop, finding the newly created subfolders and going on nesting the same subfolder over and over until it reaches a "Path name too long max 260 charachters limit exception".
I tried to avoid it by using the condition
|| drs.Substring(drs.Length-8) == "archive")
which should check the directory name, but it doesn't seem to work.
I thought than, different solutions like putting a max subfolders depth scan (I.E max 2 subfolders) so it doesn't keep rescanning all the nested folders, but I can't find such property in Directory object.
I cannot copy the whole thing to a temp folder and then into the real folder because the next time I will scan it, it will rescan archive folder too.
I tought about putting all the directory listing in an ArrayList of Directory objects or so so maybe I can check something like DirName or so but I don't know if such property exists.
Any solution?
This is a case where recursion doesn't really work, as the list of directories and files always changes as you copy. A better solution is to get the list of all files and folders in advance.
You can get all files and directories in a tree using the Directory.GetFiles(String,String,SearchOption) and Directory.GetDirectories(String,String,SearchOption) with SearchOption set to SearchOption.AllDirectories. These will return all files and all directories respectively.
You can follow these steps to copy the files:
Get the list of all source directories and sort them in ascending order. This will ensure that parent directories appear before their child directories.
Create the target directory structure by creating the child directories in their sorted order. You won't get any path conflicts as the sort order ensures you always create the parent folders before the child folders
Copy all the source files to the target directories as before. Order doesn't really matter at this point as the target directory structure already exists.
A quick example:
static void Main(string[] args)
{
var sourcePath = #"c:\MyRoot\TestFolder\";
var targetPath = #"c:\MyRoot\TestFolder\Archive\";
var directories=Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories);
var files = Directory.GetFiles(sourcePath, "*", SearchOption.AllDirectories);
if(!Directory.Exists(targetPath))
Directory.CreateDirectory(targetPath);
foreach (var directory in directories)
{
var relativePath = GetRelativePath(sourcePath, directory);
var toPath = Path.Combine(targetPath, relativePath);
if (!Directory.Exists(toPath))
{
Directory.CreateDirectory(toPath);
}
}
foreach (var file in files)
{
var relativePath = GetRelativePath(sourcePath, file);
var toPath = Path.Combine(targetPath, relativePath);
if (!File.Exists(toPath))
File.Copy(file,toPath);
}
}
//This is a very quick and dirty way to get the relative path, only for demo purposes etc
private static string GetRelativePath(string rootPath, string fullPath)
{
return Path.GetFullPath(fullPath).Substring(rootPath.Length);
}
I need to get path for each file in directories
eg: c:/a/b/c/1.jar and c:/dir/bin/2.jar must be saved as string
"c:/a/b/c/1.jar; c:/dir/bin/2.jar;..."
But the folders name may change in the future and I don't want to write this manually
Thanks for help
EDIT 1:
I've got the folder with few folders into. in each folder is files. I need to get all files directory in one string. eg: "dir1; dir2; dir3; ..."
but I can give only directory of main folder "c:/bin"
EDIT 2: Solved by Sayse
You can use Directory.EnumerateFiles
var allFiles = Directory.EnumerateFiles(sourceDirectory,
"*.*", //also can use "*.jar" here for just jar files
SearchOption.AllDirectories);
If you wish for all files to be in one long string then you can use
var fileString = string.Join(",", allFiles);
If its only directories you want
var allDirs = Directory.EnumerateDirectories("...",
"*",
SearchOption.AllDirectories);
var dirString = string.Join(";", allDirs);
class Program
{
static void Main(string[] args)
{
DirectoryInfo di = new DirectoryInfo("C:\\");
FullDirList(di, "*");
Console.WriteLine("Done");
Console.Read();
}
static string myfolders = "";// Your string, which inclueds the folders like this: "c:/a/b/c; c:/dir/bin;..."
static string myfiles = ""; // Your string, which inclueds the file like this: "c:/a/b/c/1.jar; c:/dir/bin/2.jar;..."
static List<FileInfo> files = new List<FileInfo>(); // List that will hold the files and subfiles in path
static List<DirectoryInfo> folders = new List<DirectoryInfo>(); // List that hold direcotries that cannot be accessed
static void FullDirList(DirectoryInfo dir, string searchPattern)
{
// Console.WriteLine("Directory {0}", dir.FullName);
// list the files
try
{
foreach (FileInfo f in dir.GetFiles(searchPattern))
{
//Console.WriteLine("File {0}", f.FullName);
files.Add(f);
myfiles += f.FullName + ";";
}
}
catch
{
Console.WriteLine("Directory {0} \n could not be accessed!!!!", dir.FullName);
return; // We alredy got an error trying to access dir so dont try to access it again
}
// process each directory
// If I have been able to see the files in the directory I should also be able
// to look at its directories so I dont think I should place this in a try catch block
foreach (DirectoryInfo d in dir.GetDirectories())
{
myfolders += d.FullName + ";";
folders.Add(d);
FullDirList(d, searchPattern);
}
}
}
myfiles includes all files , like "C:\MyProgram1.exe;C:\MyFolder\MyProgram2.exe;C:\MyFolder2\MyProgram2.dll"
myfolder inclueds all folders, like "C:\MyFolder;C:\MyFolder2";
I wanna do a C# application that does this:
Selects a folder
Copies all the files from that folder into that folder +/results/
Very simple, but can't get it work.
Here is my code:
string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath);
foreach (string file in files)
{
MessageBox.Show(Path.GetFullPath(file));
//string path=Path.Combine(Path.GetFullPath(file), "results");
//MessageBox.Show(path);
string path2 = Path.GetDirectoryName(file);
path2 = Path.Combine(Path.GetDirectoryName(file), #"results\");
path2 = Path.Combine(path2, file);
MessageBox.Show(path2);
}
First, create the destination directory, if not exists
string[] files = Directory.GetFiles(folderBrowserDialog1.SelectedPath);
string destPath = Path.Combine(folderBrowserDialog1.SelectedPath, "results");
if(Directory.Exists(destPath) == false)
Directory.CreateDirectory(destPath);
then inside your loop
foreach (string file in files)
{
string path2 = Path.Combine(destPath, Path.GetFileName(file));
File.Move(file, path2);
}
Please note that File.Move cannot be used to overwrite an existing file.
You will get an IOException if the file exist in the destination directory.
If you only want to copy, instead of Move, simply change the File.Move statement with File.Copy(file, path2, true);. This overload will overwrite your files in the destination directory without questions.
If you are trying to move the files (and not copy them) to the new sub-folder then...
DirectoryInfo d = new DirectoryInfo(folderBrowserDialog1.SelectedPath);
foreach (FileInfo f in d.GetFiles())
{
string fold = Path.Combine(f.DirectoryName, #"results\");
if (!Directory.Exists(fold))
Directory.CreateDirectory(fold);
File.Move(f.FullName, Path.Combine(fold, f.Name));
}
This is just an example to answer the question directly but you should also handle exceptions, etc. For instance, this example assumes the user will have permission to create the directory. Furthermore, it assumes file(s) do not already exist in the destination directory with the same name(s). How you handle such scenarios depends on your requirements.
If you want to relocate the entire directory, you can use Directory.Move to achieve this.
string path1 = Path.GetDirectoryName(file);
string path2 = Path.Combine(Path.GetDirectoryName(file), #"results\");
Directory.Move(path1, path2);
Or if you just want to copy the folder (without deleting the first directory), you'll need to do it manually.
string path1 = Path.GetDirectoryName(file);
string path2 = Path.Combine(Path.GetDirectoryName(file), #"results\");
foreach(var file in Directory.GetFiles(path1))
{
File.Copy(file, Path.Combine(path2, file));
// File.Move(file, Path.Combine(path2, file)); // use this to move instead of copy
}
I haven't tested this, so some modifications might be necessary