I want to copy some of the content of a folder (recursively). only files that contain a specific pattern.
Here there's a method that copies the entire content. no matter what files inside.
https://stackoverflow.com/a/3822913/7028967
Do you have any ideas on how can I copy a specific file inside some subfolder with a given pattern?
for example:
-- rootFolder
---- filename.txt
CopyContent(src, dest, *.txt)
Below sample code to copy all the files from the source directory to destination folder in exact same folder structure :
public static void Copy()
{
string sourceDir = #"C:\test\source\";
string destination = #"C:\test\destination\";
string[] textFiles = Directory.GetFiles(sourceDir, "*.txt", SearchOption.AllDirectories);
foreach (string textFile in textFiles)
{
string fileName = textFile.Substring(sourceDir.Length);
string directoryPath = Path.Combine(destination, Path.GetDirectoryName(fileName));
if (!Directory.Exists(directoryPath))
Directory.CreateDirectory(directoryPath);
File.Copy(textFile, Path.Combine(directoryPath, Path.GetFileName(textFile)), true);
}
}
Updated:
I used this solution. and it works for me!
private static void CopyContentFolder(string sourcePath, string targetPath, bool isFileOverridable, string pattern = "*.*")
{
string[] sourceFiles = Directory.GetFiles(sourcePath, pattern, SearchOption.AllDirectories);
foreach (string sourceFilePath in sourceFiles)
{
string destinationFilePath = string.Empty;
destinationFilePath = sourceFilePath.Replace(sourcePath, targetPath);
EvaluatePath(destinationFilePath);
File.Copy(sourceFilePath, destinationFilePath, isFileOverridable);
}
}
private static void EvaluatePath(string path)
{
try
{
string folder = Path.GetDirectoryName(path);
if (!Directory.Exists(folder))
{
DirectoryInfo di = Directory.CreateDirectory(folder);
}
}
catch (IOException ioex)
{
Console.WriteLine(ioex.Message);
}
}
Related
This question already has answers here:
Copy the entire contents of a directory in C#
(28 answers)
Copy file from one directory to another
(5 answers)
Closed 5 years ago.
Okay, so I have a text box in my program where a user can enter a value, however I am wanting to call this value in another class.
public static void Main()
{
string sourceDirectory = #"F:\RootFolder\testingfolder\Test";
string targetDirectory = #"c:\targetDirectory"; //this is where the value would site
Copy(sourceDirectory, targetDirectory);
}
Not 100% sure on how to call this.
Edit
After some much needed research I have found the below to work for me;
private void CopyInstallFiles(object sender, EventArgs e)
{
string sourceDirectory = #"F:somepath";
string targetDirectory = directoryImput.Text;
//Copy all the files & Replaces any files with the same name
foreach (string newPath in System.IO.Directory.GetFiles(sourceDirectory, "*.*",
SearchOption.AllDirectories))
File.Copy(newPath, newPath.Replace(sourceDirectory, targetDirectory), true);
I just realized that you are looking for a method to move all files and folders - silly me. Here, have some example from https://msdn.microsoft.com/en-us/library/bb762914.aspx :
using System;
using System.IO;
class DirectoryCopyExample
{
static void Main()
{
// Copy from the current directory, include subdirectories.
DirectoryCopy(".", #".\temp", true);
}
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
DirectoryInfo[] dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
}
Short version - place it in DirectoryManager.cs and call by DirectoryManager.CopyDirectory(source, destination):
using System.IO;
class DirectoryManager
{
internal static void CopyDirectory(string input, string output)
{
DirectoryInfo dir = new DirectoryInfo(input);
if (dir.Exists)
{
DirectoryInfo[] dirs = dir.GetDirectories();
Directory.CreateDirectory(output);
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(output, file.Name);
file.CopyTo(temppath, false);
}
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(output, subdir.Name);
CopyDirectory(subdir.FullName, temppath);
}
}
}
}
I did the following, but i don't see the zip file in the directroy. C#
public static void AddToZip(string fileToAdd, string directory)
{
string entryName = fileToAdd.Replace(directory, string.Empty);
string archiveName = entryName.Replace(Path.GetExtension(entryName), ".zip");
using (ZipArchive za = ZipFile.Open(archiveName, ZipArchiveMode.Create))
{
za.CreateEntryFromFile(fileToAdd, entryName, CompressionLevel.Optimal);
}
}
and this is the link i followed.
http://msdn.microsoft.com/en-us/library/system.io.compression.ziparchive(v=vs.110).aspx
Finally got it working after some trial and error.
public static void AddToZip(string fileToAdd, string directory)
{
string entryName = fileToAdd.Replace(directory, string.Empty);//name of the file inside zip archive
string tempDir = Path.Combine(directory, Path.GetFileNameWithoutExtension(entryName));
if (Directory.Exists(tempDir)) DeleteDirector(tempDir);
else Directory.CreateDirectory(tempDir);
System.IO.File.Move(fileToAdd, Path.Combine(tempDir, entryName));//as the CreateFromDirectoy add all the file from the directory provided, we are moving our file to temp dir.
string archiveName = entryName.Replace(Path.GetExtension(entryName), ".zip"); //name of the zip file.
ZipFile.CreateFromDirectory(tempDir, Path.Combine(directory, archiveName));
DeleteDirector(tempDir);
}
private static void DeleteDirector(string deletedir)
{
foreach (string file in Directory.GetFiles(deletedir))
{
System.IO.File.Delete(file);
}
Directory.Delete(deletedir);
}
I know this is not the best solution. so, you are welcome to modify/improve it.
In C#.NET, How to copy a file to another location, overwriting the existing file if the source file is newer than the existing file (have a later "Modified date"), and doing noting if the source file is older?
You can use the FileInfo class and it's properties and methods:
FileInfo file = new FileInfo(path);
string destDir = #"C:\SomeDirectory";
FileInfo destFile = new FileInfo(Path.Combine(destDir, file.Name));
if (destFile.Exists)
{
if (file.LastWriteTime > destFile.LastWriteTime)
{
// now you can safely overwrite it
file.CopyTo(destFile.FullName, true);
}
}
You can use the FileInfo class:
FileInfo infoOld = new FileInfo("C:\\old.txt");
FileInfo infoNew = new FileInfo("C:\\new.txt");
if (infoNew.LastWriteTime > infoOld.LastWriteTime)
{
File.Copy(source path,destination path, true) ;
}
Here is my take on the answer: Copies not moves folder contents. If the target does not exist the code is clearer to read. Technically, creating a fileinfo for a non existent file will have a LastWriteTime of DateTime.Min so it would copy but falls a little short on readability. I hope this tested code helps someone.
**EDIT: I have updated my source to be much more flexable. Because it was based on this thread I have posted the update here. When using masks subdirs are not created if the subfolder does not contain matched files. Certainly a more robust error handler is in your future. :)
public void CopyFolderContents(string sourceFolder, string destinationFolder)
{
CopyFolderContents(sourceFolder, destinationFolder, "*.*", false, false);
}
public void CopyFolderContents(string sourceFolder, string destinationFolder, string mask)
{
CopyFolderContents(sourceFolder, destinationFolder, mask, false, false);
}
public void CopyFolderContents(string sourceFolder, string destinationFolder, string mask, Boolean createFolders, Boolean recurseFolders)
{
try
{
if (!sourceFolder.EndsWith(#"\")){ sourceFolder += #"\"; }
if (!destinationFolder.EndsWith(#"\")){ destinationFolder += #"\"; }
var exDir = sourceFolder;
var dir = new DirectoryInfo(exDir);
SearchOption so = (recurseFolders ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
foreach (string sourceFile in Directory.GetFiles(dir.ToString(), mask, so))
{
FileInfo srcFile = new FileInfo(sourceFile);
string srcFileName = srcFile.Name;
// Create a destination that matches the source structure
FileInfo destFile = new FileInfo(destinationFolder + srcFile.FullName.Replace(sourceFolder, ""));
if (!Directory.Exists(destFile.DirectoryName ) && createFolders)
{
Directory.CreateDirectory(destFile.DirectoryName);
}
if (srcFile.LastWriteTime > destFile.LastWriteTime || !destFile.Exists)
{
File.Copy(srcFile.FullName, destFile.FullName, true);
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message + Environment.NewLine + Environment.NewLine + ex.StackTrace);
}
}
In a batch file, this will work:
XCopy "c:\my directory\source.ext" "c:\my other directory\dest.ext" /d
I have been using the following lines to search a folder structure for specific filetypes and just copy those filetypes and maintain their original folder structure. It works very well.
Is there any modification I can make to my method to only copy the directories that contain the filtered filetype?
*edit: I can let the user select a only certain set of files, (example *.dwg or *.pdf), using text box named txtFilter.
private void button1_Click(object sender, EventArgs e)
{
string sourceFolder = txtSource.Text;
string destinationFolder = txtDestination.Text;
CopyFolderContents(sourceFolder, destinationFolder);
}
// Copies the contents of a folder, including subfolders to an other folder, overwriting existing files
public void CopyFolderContents(string sourceFolder, string destinationFolder)
{
string filter = txtFilter.Text;
if (Directory.Exists(sourceFolder))
{
// Copy folder structure
foreach (string sourceSubFolder in Directory.GetDirectories(sourceFolder, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
}
// Copy files
foreach (string sourceFile in Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories))
{
string destinationFile = sourceFile.Replace(sourceFolder, destinationFolder);
File.Copy(sourceFile, destinationFile, true);
}
}
}
Something like this in your main loop?
if (Directory.EnumerateFiles(sourceSubFolder, "*.pdf").Any())
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
or for multiple file types:
if (Directory.EnumerateFiles(sourceSubFolder).Where(x => x.ToLower.EndsWith(".pdf") || x.ToLower.EndsWith(".dwg")).Any())
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
You can simply concatenate both operations into one loop and complete the algorithm in O(n).
foreach(string sourceFile in Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories))
{
Directory.CreateDirectory(Path.GetDirectoryName(sourceFile.Replace(sourceFolder,destinationFolder)));
File.Copy(sourceFile,sourceFile.Replace(sourceFolder,destinationFolder),true);
}
You can get the distinct directories from the files you find, then iterate through them and create the directories before copying the files.
if (Directory.Exists(sourceFolder))
{
var files = Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories);
foreach(string directory in files.Select(f => Path.GetDirectoryName(f)).Distinct())
{
string destinationDirectory = directory.Replace(sourceFolder, destinationFolder);
if (!Directory.Exists(destinationDirectory))
{
Directory.CreateDirectory(destinationDirectory);
}
}
foreach (string sourceFile in files)
{
string destinationFile = sourceFile.Replace(sourceFolder, destinationFolder);
File.Copy(sourceFile, destinationFile, true);
}
}
how do i allow this code to retrieve the files from a directory? For example, my directory name is "Folder Name":
private ObservableCollection<FileItem> LoadFiles()
{
ObservableCollection<FileItem> files = new ObservableCollection<FileItem>();
foreach (string filePath in this.Store.GetFileNames())
files.Add(new FileItem { FileName = filePath });
return files;
}
EDIT:
I've tried this, and it still isn't working:
private ObservableCollection<FileItem> LoadFiles()
{
ObservableCollection<FileItem> files = new ObservableCollection<FileItem>();
foreach (string filePath in this.Store.GetFileNames())
files.Add(new FileItem { "FlashCardApp\\" + FileName = filePath });
return files;
}
I've finally found the answer to my own question.
This is how it is suppose to be:
private ObservableCollection<FileItem> LoadFiles()
{
ObservableCollection<FileItem> files = new ObservableCollection<FileItem>();
foreach (string filePath in this.Store.GetFileNames("FlashCardApp\\"))
files.Add(new FileItem { FileName = filePath });
return files;
}
By having \ after the folder name, "FlashCardApp\\", it will retrieve the files from the directory.
DirectoryInfo di = new DirectoryInfo("c:/Folder Name");
FileInfo[] rgFiles = di.GetFiles("*.*");
foreach(FileInfo fi in rgFiles)
{
//Do something
fi.Name
}
To retrieve file names, you can use System.IO:
string[] filePaths = Directory.GetFiles(path, "*.txt")
The Directory class is in System.IO.
I doubth that your folder name is correct. I'll recommend you use storeFile.GetDirectoryNames("*") to see what the correct paths for the directory is.
Microsoft wrote a great example I think you should try and take a look at, since there's nothing obvious wrong with your code.