How to Copy and move files and folders in C# [duplicate] - c#

This question already has answers here:
Copy Folders in C# using System.IO
(9 answers)
Closed 4 years ago.
How can we copy and move folders in one folder to another folder.
void BtncopyClick(object sender, EventArgs e)
{
string filename=#"E:\\Files\\Reports\\R^ECG^_0_1688^Jones^^_20160711065157_20160711065303 - Copy (4) - Copy.pdf";
string sourcepath=#"E:\\Anusha";
string targetpath=#"E:\\Anusha\\aaa";
string sourcefile= System.IO.Path.Combine(sourcepath,filename);
string destfile= System.IO.Path.Combine(targetpath,filename);
if (!System.IO.Directory.Exists(targetpath))
{
System.IO.Directory.CreateDirectory(targetpath);
}
System.IO.File.Copy(sourcefile, destfile, true);
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
{
MessageBox.Show("File doesn't exist");
}
}
void BtnmoveClick(object sender, EventArgs e)
{
String path = "E:\\Files\\25-11-2017";
String path2 = "E:\\Anusha\\aaa\\25-11-2017";
if (!File.Exists(path))
{
{
// This statement ensures that the file is created,
// but the handle is not kept.
using (FileStream fs = File.Create(path)) {}
}
System.IO.Directory.Move("E:\\Files\\25-11-2017",#"E://Anusha//aaa");
// Move the file.
File.Move(path, path2);
MessageBox.Show("File Moved");
}
}
I have the above code to copy and move the folder,I am not getting any compiling errors. However, when i am trying to click on button on the output form it was showing as termination.
Update
Code works with out any error but it was getting termination Error as cannot create a file as it is already exists

Hope this helps
How to: Copy, Delete, and Move Files and Folders (C# Programming Guide)
You can use System.IO.File, System.IO.Directory, System.IO.FileInfo, and System.IO.DirectoryInfo classes from the System.IO namespace.

I am not sure what you are trying to do, but I am seeing a lot of problems here.
1) In the line
System.IO.Directory.Move("E:\\Files\\25-11-2017",#"E://Anusha//aaa");
you are using // as directory separator in the second argument. You should change it to
System.IO.Directory.Move("E:\\Files\\25-11-2017","E:\\Anusha\\aaa");
2) Sometimes you are using verbatim strings incorrectly. For example, in the line
string sourcepath=#"E:\\Anusha";
you are using a verbatim string which means that the compiler ignores the escape sequences in that string. Hence, your application later won't find that path. Instead, use one of the following:
string sourcepath=#"E:\Anusha";
string sourcepath="E:\\Anusha";
3) The structure of your BtnmoveClick is quite weird. The line
System.IO.Directory.Move("E:\\Files\\25-11-2017","E:\\Anusha\\aaa");
moves the contents of E:\files\25-11-2017 to E:\Anusha\aaa, but only if the latter does NOT exist yet. If it already exists, that line will cause an exception (which probably makes your application terminate).
Furthermore, after you already have moved the directory contents in the line shown above, you are again trying to move something in the line
File.Move(path, path2);
But path and path2 are strings which describe directories, not files, so I wouldn't do it that way. Furthermore, since you already have moved the directory (more precise: its contents) in the previous line, I am asking myself what exactly the purpose of that line is.
I didn't look into your BtncopyClick yet, so let's concentrate on BtnmoveClick for now. Please try to fix the issues described so far, and if you have further issues, report back.
As a general recommendation: If you really want to learn C#, then don't copy-and-paste randomly selected examples; you'll never learn anything useful that way. Instead, read the documentation of the .net framework on MSDN or read a good book - this will gain you a deep understanding.

Related

Directory.Move(SourcePath, Destinationpath ) is failing in c#

I believed this to be really simple but somehow i am making a mistake.I am trying to copy one folder to another location
Directory.Move(SourcePath, Destinationpath )
This expression is failing. The exception thrown is "cannot create file that already exists"
Well, you say you want to "copy one folder to another".
Directory.Move(), doesn't copy: as its name implies, it moves a directory. Take at look at the documentation on how to copy files:
.Net 4.0 (see here for an asynchronous approach)
.Net 4.5 (see here for an asynchronous approach)
The Move call is failing because a directory or file in the move operation exists at the specified location (as the exception noted). In order to fix this you need to ensure that no file or directory exists at the destination. The easiest way is to first delete that path
Do not run this function unless you are OK with unconditionally deleting data at DestinationPath.
static void MyMove(string sourcePath, string destPath) {
try {
Directory.Delete(destPath, recursive: true);
} catch {
// Don't care if this fails. If the file didn't exist, great, if the
// file can't be deleted will still get an error in Move. Just try
// Move at this point
}
Directory.Move(sourcePath, destPath);
}

C# Overwrite file failed badly

Tried several times to make this work but with several failures.
let me explain what i've tried to do: 1.Unrar the files in zip format (working) 2.Unraring to a named directory (unrars) 3.Copying from unrars folder to another folder(not working) So my question is : Did i used a correct overwrite format? i set the bool overwrite to true.
foreach (string fisier in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories))
{
System.IO.File.Copy(fisier, fisier.Replace(TheSourcePath, TheDestinationPath), true);
}
Seems like an odd way to get the destination path to me, can't you just have it as a string?
It might be that the string replace isn't creating a valid path.
I assume `TheDestinationPath' is a const, in which case is won't have the file name on it, or you'll be copying over a file from the second iteration.

Copy all files in directory

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("\\"))));

I have a problem with the function Directory.delete?

Take a look at my code:
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
try
{
if (Directory.Exists(Path.Combine(desktopPath, "Hackers.avi")))
Directory.Delete(Path.Combine(desktopPath, "Hackers.avi"), true);
after runing the file is still exist on my desktop , why??
It is unlikely that Hackers.avi is a directory - .avi is normally used an extension for a video file (see Audio Video Interleave on Wikipedia for more information).
Try using File.Delete instead of Directory.Delete:
string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
try
{
string pathToFile = Path.Combine(desktopPath, "Hackers.avi");
File.Delete(pathToFile);
// etc...
I also omitted the call to File.Exists because you don't have to check for a file's existence before deleting it. File.Delete does not throw if the file doesn't exist.
You want to delete file, sou you must use 'File.Delete'

Securely enforcing user-input file paths within subdirectories

I know the solid security recommendation of avoiding accepting user input that you then use to choose a path to read/write a file. However, assuming you have a base directory you want to keep within (such as the root of an ftp folder), how do you best ensure that a given user input keeps us within that folder?
For instance,
Path.Combine(_myRootFolder, _myUserInput)
could still take us outside of _myRootFolder. And this could also be dodgy
newPath = Path.Combine(_myRootFolder, _myUserInput)
if (newPath.StartsWith(_myRootFolder))
...
given something like "/back/to/myrootfolder/../../and/out/again" from the user. What are the strategies for this? Am I missing a blindingly obvious .NET method I can use?
Within ASP.NET applications you can use Server.MapPath(filename) which will throw an exception if the path generated goes outside of your application root.
If all you want is a safe file name and you just want all files in there it becomes simpler;
FileInfo file = new FileInfo(
Server.MapPath(
Path.Combine(#"c:\example\mydir", filename)));
If you're outside of ASP.NET like you indicate then you could use Path.GetFullPath.
string potentialPath = Path.Combine(#"c:\myroot\", fileName);
if (Path.GetFullPath(potentialPath) != potentialPath)
// Potential path transversal
Or you call Path.GetFullPath and then check the start of it matches the directory you want locked to.
I know, that this thread is quiet old, but to prevent following readers from writing code with potential security errors, I think I should point out, that using Path.Combine(arg1, arg2) isn't save when arg2 is directly based on user input.
When arg2 is for example "C:\Windows\System32\cmd.exe" the arg1 parameter will be completely ignored and you grant the users of your API or server application full access to the whole file system.
So please be very careful with using this method!
I came up with this solution that should (afaik) be secure:
public static string SecurePathCombine(params string[] paths)
{
string combinedPath = "";
foreach (string path in paths)
{
string newPath = Path.Combine(combinedPath, path);
if (!newPath.StartsWith(combinedPath))
return null;
combinedPath = newPath;
}
if (Path.GetFullPath(combinedPath) != combinedPath)
return null;
return combinedPath;
}
Edit: There is a new Path.Join() method now. Please use that one instead of the code above.
I believe Path.FullPath will do what you need (I didn't test this though):
string newPath = Path.Combine(_myRootFolder, _myUserInput);
string newPath = Path.FullPath(newPath);
if (newPath.StartsWith(_myRootFolder)) ...
Well, in your example of an FTP server, you should set the users home-directory, and permissions appropriately, such that they can't navigate out of the folder. Any reason you can't do that?
You can parse input string and cut ../ with regex.

Categories

Resources