I trying to write a code that will copy all files from give directory and its all sub directories. (Only copy files not directories).
This is so far i have
public static void Copy(string sourceDir, string targetDir)
{
Directory.CreateDirectory(targetDir);
foreach(var file in Directory.GetFiles(sourceDir))
File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)),true);
foreach(var directory in Directory.GetDirectories(sourceDir))
Copy(directory, Path.Combine(targetDir, Path.GetFileName(directory)));
}
I am facing two problems here.
I get unauthorized Access exception. There is a folder in source directory that is creating problem.
2nd problem is. If it copies it copy all files and folder as it is in the source directory. but I only need files.
Any solution for both problems ?
OK to copy all sub directories, and so on, omitting any that wont let you have access:
Before you call copy, you would need to check targetDir exists.
if (!Directory.Exists(targetDir)) Directory.CreateDirectory(targetDir);
you should really check it can do that etc, then to recursively copy the folders into the same one:
public static void Copy(string sourceDir, string targetDir)
{
try
{
foreach(var file in Directory.GetFiles(sourceDir))
try
{ File.Copy(file, Path.Combine(targetDir, Path.GetFileName(file)),true);}
catch {} // you could do other things to handle different issues - like lack of space, etc
foreach(var directory in Directory.GetDirectories(sourceDir))
Copy(directory, targetDir)); // this will go into each subdirectory, and do the same.
}
catch {} // catches unable to access directory you've gone into
}
}
You keep the final destination the same if you wanted a flat dump into a folder, by trying to append the path etc to copy you were recreating the whole directory structure.
Related
I'm having problems keeping 1 folder which contains an image I want to keep.
I'm currently using the code below:
DirectoryInfo di = new DirectoryInfo(pathToMedia);
foreach (var image in di.GetFiles())
{
if (!image.Name.Contains(emailImage))
{
di.Delete(true);
}
}
The above does not work as I cannot seem to get the file name of the image inside the sub-folder, any help would be appreciated
The code is not able to find the file as GetFiles(string) method only returns the file in the current directory and not in the sub-folders (an overload exists which allows to get all files, but that wont be useful here as we need the directory information as well). If you want to check for the files in all sub-folders then you will have to recursively do through the entire structure.
The code below shows how to do it, in your case instead of writing to console you will just check if it matches to the file you are searching.
You can see the detail about these methods in api documentation
As mentioned in the documentation it might be beneficial for you to use EnumerateFiles in case your folders are going to have a large number of files.
// Process all files in the directory passed in, recurse on any directories
// that are found, and process the files they contain.
public static void ProcessDirectory(string targetDirectory)
{
// Process the list of files found in the directory.
string [] fileEntries = Directory.GetFiles(targetDirectory);
foreach(string fileName in fileEntries)
ProcessFile(fileName);
// Recurse into subdirectories of this directory.
string [] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach(string subdirectory in subdirectoryEntries)
ProcessDirectory(subdirectory);
}
// Insert logic for processing found files here.
public static void ProcessFile(string path)
{
Console.WriteLine("Processed file '{0}'.", path);
}
I want to do something simple. Take the contents of folder A and move the files and folders into a folder within folder A. Then make folder A hidden.
The code below is getting an exception of hiddenTarget is not found.
Directory.Create(hiddenTarget) is not helping
There must be a simple way to do this. Currently I am attempting to make a temp directory. Put all files from the current directory in it. Then Move the temp directory to the current directory. Then make the current directory hidden.
Here is the code in issue..
string tempFolder = Path.Combine(Environment.ExpandEnvironmentVariables("%TEMP%"), "tempTarget");
//Directory.CreateDirectory(tempFolder);
Directory.Move(currentTarget, tempFolder);
string hiddenTarget = Path.Combine(currentTarget, #".bak");
//Directory.CreateDirectory(hiddenTarget);
Directory.Move(tempFolder, hiddenTarget);
DirectoryInfo di = new DirectoryInfo(currentTarget);
di.Attributes = FileAttributes.Directory | FileAttributes.Hidden;
So you have two issues here first is that your hidden target cannot start with a '.' because as pointed out in the comments that is illegal in NTFS.
As you can see File Explorer doesn't like this syntax.
As pointed out by #Dour High Arch here is the link to the relevant information: Naming Files, Paths, and Namespaces
Your next issue is that the move is destroying the original directory structure. Therefore, your steps need to be as follows:
1) Move to a temporary directory to avoid any issues with the two processes (file system & your process) fighting for access.
2) Due to the fact that the Directory.Move in step #1 destroyed the original source directory. Recreate the destroyed source folder.
3) Then move into the desired nested folder. This move operation will automatically create the desired sub-directory. Step #2 is required because for whatever reason I'm still looking into Directory.Move cannot automatically create the structure without the source directory already existing.
string currentTarget = #"C:\A";
string hiddenTarget = #"C:\A\Subfolder";
string tempTarget = #"C:\Temp";
Directory.Move(currentTarget, tempTarget);
Directory.CreateDirectory(currentTarget);
Directory.Move(tempTarget, hiddenTarget);
DirectoryInfo di = new DirectoryInfo(currentTarget);
di.Attributes = FileAttributes.Directory | FileAttributes.Hidden;
Update
From an engineering perspective you really should be performing copies if you really care about the data being moved. It may be slower, but will help prevent any horrible things from happening to the data. You should check whether or not these directories exist first before creating them. Exception handling within this example is at a minimum as well. What I'm really trying to stress here is handle the data that is being moved with care!
static void Main(string[] args)
{
string sourceDir = #"C:\Src";
string tempDir = #"C:\Temp";
string destDir = Path.Combine(sourceDir, "Dest");
// Could optionally check to verify that the temp directory already exists here and destroy it if it does.
// Alternatively, pick a really unique name for the temp directory by using a GUID, Thread Id or something of that nature.
// That way you can be sure it does not already exist.
// Copy to temp, then destroy source files.
CopyDirectory(sourceDir, tempDir);
Directory.Delete(sourceDir, true);
// Copy to dest
CopyDirectory(tempDir, destDir);
// Hide the source directory.
DirectoryInfo di = new DirectoryInfo(sourceDir);
di.Attributes = FileAttributes.Directory | FileAttributes.Hidden;
// Clean up the temp directory that way copies of the files aren't sitting around.
// NOTE: Be sure to do this last as if something goes wrong with the move the temp directory will still exist.
Directory.Delete(tempDir, true);
}
/// <summary>
/// Recursively copies all subdirectories.
/// </summary>
/// <param name="sourceDir">The source directory from which to copy.</param>
/// <param name="destDir">The destination directory to copy content to.</param>
static void CopyDirectory(string sourceDir, string destDir)
{
var sourceDirInfo = new DirectoryInfo(sourceDir);
if (!sourceDirInfo.Exists)
{
throw new DirectoryNotFoundException($"Source directory does not exist or could not be found: '{sourceDir}'");
}
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDir))
{
Directory.CreateDirectory(destDir);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = sourceDirInfo.GetFiles();
foreach (FileInfo file in files)
{
string tempPath = Path.Combine(destDir, file.Name);
file.CopyTo(tempPath, false);
}
// Copy subdirectories
DirectoryInfo[] subDirs = sourceDirInfo.GetDirectories();
foreach (DirectoryInfo subdir in subDirs)
{
string tempPath = Path.Combine(destDir, subdir.Name);
CopyDirectory(subdir.FullName, tempPath);
}
}
Here are a few more links regarding the above.
MSDN - How to: Copy Directories
Stack Overflow - How to copy the entire contents of directory in C#?
I have list of files which i need to copy to a different share folder with same folder structure.
Input:
\\myshare1\foldername1\foldername2\file1.txt
\\myshare1\foldername1\foldername2\file2.txt
\\myshare1\foldername3\foldername4\file1.txt
\\myshare1\foldername3\foldername1\file4.txt
Output : Copy all the files to \\myshare2 with the same folder structure. If the folder is there skip the folder creation and if not create the folder.
\\myshare2\foldername1\foldername2\file1.txt
\\myshare2\foldername1\foldername2\file2.txt
\\myshare2\foldername3\foldername4\file1.txt
\\myshare2\foldername3\foldername1\file4.txt
Just do a foreach on your folder to get all the file names and send each file to the following method
public void CopyFiles(string sourcePath)
{
string destination = "myshare2";
string source = sourcePath.Replace("myshare1","");
if (!System.IO.Directory.Exists($"{destination}{source}"))
{
System.IO.Directory.CreateDirectory($"{destination}{source}");
System.IO.File.Copy(sourcePath, $"{destination}{source}", true);
}
}
Hello I am attempting to copy a directory and its subdirectories from my D drive to a shared network but I continue getting the error as
Exception:
Could not find a part of the path '/Projects/08.ASP.NETProjects/ProjectName/'.
My C# copy code:
System.IO.DirectoryInfo directory = new System.IO.DirectoryInfo(D drive path);
var destinationpath = "file:///BZ0025BZV43/Projects/08.ASP.NETProjects/ProjectName/";
var uri = new Uri(destinationpath);
var destinationurl = uri.AbsolutePath;
foreach (System.IO.FileInfo mydirectory in directory.GetFiles())
mydirectory .CopyTo(destinationurl);
I am new to FileHandlers. Please help.
Try to use uri.LocalPath instead of uri.AbsolutePath.
Also, be aware that you are trying to copy a file into a directory. But you have to copy the file into another file of that directory. (Directories are files too, basically).
So to do that check if the target directory exists and create it when necessary. Then replace .copyTo(destinationUrl) with .copyTo(Path.Combine(uri.LocalPath, mydirectory.Name)) and you should be good to go. And please rename the variable mydirectory to file or something similar.
Also note that you are not copying the directory tree recursively. So if you want to recurse the tree, you have to check for subdirectories and copy the files in that hierarchy, too.
You can also check out this example: http://msdn.microsoft.com/de-de/library/bb762914(v=vs.110).aspx
I was trying to move a file from my Resx to my PC, but I'm keep having problems.
So I import a folder named "bad" in the Resources and I use the File.Move method to move the folder "bad" into my PC.
But the program keeps crashing because it says: Cannot create a file when its already exists.
Here the code I use:
//txtpath is the root folder. I let the user choose the root folder and save it in txtpath.text
private void btnbadname_Click(object sender, EventArgs e)
{
string source = "Resources\bad";
string destination = txtpath.Text + #"\RADS\projects\lol_air_client\releases\0.0.1.74\deploy\assets\locale\App";
File.Move(source, destination);
MessageBox.Show("脏话ID已开启, 教程请点击下面的链接");
}
The destination Directory cannot exist. In your code you are creating the Directory if it doesn't exist and then trying to move your directory, the Move Method will create the directory for you. If the Directory already exists you will need to Delete it or Move it.
See:
Cannot create a file when that file already exists when using Directory.Move
Destination supposed to have the filename as well
string destination = txtpath.Text + #"\RADS\projects\lol_air_client\releases\0.0.1.74\deploy\assets\locale\App\yourfilename.ext";
You are using File.Move to move directory, why not using Directory.Move.
The MSDN documentation will only move files from a source to a destination, while Directory.Move will move the directory itself.
If I misunderstood you, and you want to move a file;
You can check if the file exists before or not using something like:
if(File.Exists(fileName))
File.Delete(fileName);
Edit:
If you want to iterate through the directory and make sure that the file doesn't exist before moving it, you can use something like:
//Set the location of your directories
string sourceDirectory = #"";
string destDirectory = #"";
//Check if the directory exists, and if not create it
if (!Directory.Exists(destDirectory))
Directory.CreateDirectory(destDirectory);
DirectoryInfo sourceDirInfo = new DirectoryInfo(sourceDirectory);
//Iterate through directory and check the existance of each file
foreach (FileInfo sourceFileInfo in sourceDirInfo.GetFiles())
{
string fileName = sourceFileInfo.Name;
string destFile = Path.Combine(destDirectory, fileName);
if (File.Exists(destFile))
File.Delete(destFile);
//Finally move the file
File.Move(sourceFileInfo.FullName, destFile);
}
When using MoveTo, provide the full path of where you are sending the file, including the file name, eg, pic123.jpg. If you use DirectoryInfo to get an array of files and want to move any of them, append the Name property of the file to the directory path where you are sending the file.
imgFile.MoveTo("C:\myPictures\ArchiveFolder\pic123.jpg")