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#?
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 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.
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")
How can I copy all of the contents in one directory to another with out looping over each file?
You can't. Neither Directory nor DirectoryInfo provide a Copy method. You need to implement this yourself.
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)));
foreach(var directory in Directory.GetDirectories(sourceDir))
Copy(directory, Path.Combine(targetDir, Path.GetFileName(directory)));
}
Please read the comments to be aware of some problems with this simplistic approach.
Msdn has guidance on this - How to:Copy Directories
You can use VB’s FileSystem.CopyDirectory method to simplify the task:
using Microsoft.VisualBasic.FileIO;
foo(){
FileSystem.CopyDirectory(directoryPath, tempPath);
}
using System.IO;
string sourcePath = #"D:\test";
string targetPath = #"D:\test_new";
if (!Directory.Exists(targetPath))
{
Directory.CreateDirectory(targetPath);
}
foreach (var srcPath in Directory.GetFiles(sourcePath))
{
//Copy the file from sourcepath and place into mentioned target path,
//Overwrite the file if same file is exist in target path
File.Copy(srcPath, srcPath.Replace(sourcePath, targetPath), true);
}
KISS – Keep It Simple Stupid… is a good rule of thumb for any situation, including programming.
Here is the simplest method of copying all files, folders, sub-folders and all their files and folders while keeping the original hierarchy. It also displays a nice Microsoft Windows progress dialog box.
Simply follow these basic instructions:
1: Open a new C# console application in Visual Studio – version (whatever)
2: From the menu bar; go to “Tools – Nuget Package Manager – Manage Nuget Packages for Solution” In the Nuget package manager search box, type – “Microsoft.VisualBasic” and select the “.Net” package.
3: Back on the “Program.cs” page, add the following “using” statements:
• Using System;
• Using Microsoft.VisualBasic.FileIO;
4: Inside the “Main” method, type the code provided below, replacing the source and destination paths with your folder/drives.
5: The “Console.WriteLine” line simply displays a message that it is copying and to “Please Stand by”. This line of code is completely optional. Not needed for this process to work.
6: The “FileSystem.CopyDirectory” command is a basic copy function to copy the folder and contents to the new destination. The only real difference is that the “UIOption.AllDialgs” command is added to the end of the copy command. This is the part that generates the Microsoft Windows Progress Dialog box.
Now, add the following code to your C# “Program.cs” page.
using System;
using Microsoft.VisualBasic.FileIO;
namespace ProgressDialogBox
{
class Program
{
static void Main(string[] args)
{
string sourcePath = #"c:\TestA\TestNew3";
string destinationPath = #"c:\TestB\TestNew4";
Console.WriteLine(#"Copying... {0} ... Please stand by ", sourcePath);
FileSystem.CopyDirectory(sourcePath, destinationPath, UIOption.AllDialogs);
}
}
}
This whole process takes less than 3 minutes to create. It actually takes longer to read this posting than to create and execute the program.
Enjoy.
Hope this helps someone in the future.
Here is the link from Microsoft that I used for reference:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-provide-a-progress-dialog-box-for-file-operations
This works great! It will copy sub directories or you can just dump all the files from all subdirectories into one location.
/// AUTHOR : Norm Petroff
/// <summary>
/// Takes the files from the PathFrom and copies them to the PathTo.
/// </summary>
/// <param name="pathFrom"></param>
/// <param name="pathTo"></param>
/// <param name="filesOnly">Copies all files from each directory to the "PathTo" and removes directory.</param>
public static void CopyFiles(String pathFrom, String pathTo, Boolean filesOnly)
{
foreach(String file in Directory.GetFiles(pathFrom))
{
// Copy the current file to the new path.
File.Copy(file, Path.Combine(pathTo, Path.GetFileName(file)), true);
}
// Get all the directories in the current path.
foreach (String directory in Directory.GetDirectories(pathFrom))
{
// If files only is true then recursively get all the files. They will be all put in the original "PathTo" location
// without the directories they were in.
if (filesOnly)
{
// Get the files from the current directory in the loop.
CopyFiles(directory, pathTo, filesOnly);
}
else
{
// Create a new path for the current directory in the new location.
var newDirectory = Path.Combine(pathTo, new DirectoryInfo(directory).Name);
// Copy the directory over to the new path location if it does not already exist.
if (!Directory.Exists(newDirectory))
{
Directory.CreateDirectory(newDirectory);
}
// Call this routine again with the new path.
CopyFiles(directory, newDirectory, filesOnly);
}
}
}
Execute xcopy source_directory\*.* destination_directory as an external command. Of course this will only work on Windows machines.
You can't. But you can use some sort of succinct code like Directory.GetFiles(mydir).ToList().ForEach(f => File.Copy(f, otherdir + "\\" + Path.GetFileName(f));
While the C# approach works well, it's not always the best answer. A simple DOS batch script works much better by ignoring the 256 character limit found in the C# approach.
robocopy C:\myFiles D:\masterBackup\myFiles /E /V
The only draw back I have found with the DOS batch script is that it will not (in some cases) copy SQL Server "mdf" data files and "ldf" log files using the "robocopy" command. But that's a permissions issue.
Otherwise, I have relied more on the DOS batch script for my incremental and full backups.
Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + #"resources\html")
.ToList()
.ForEach(f => File.Copy(f, folder + "\\" + f.Substring(f.LastIndexOf("\\"))));