How do I copy a directory to a different drive in C#?
You can use this code to perform your operation:
public static void CopyAll(DirectoryInfo source, DirectoryInfo target)
{
// Check if the target directory exists, if not, create it.
if (Directory.Exists(target.FullName) == false)
{
Directory.CreateDirectory(target.FullName);
}
// Copy each file into it’s new directory.
foreach (FileInfo fi in source.GetFiles())
{
Console.WriteLine(#”Copying {0}\{1}”, target.FullName, fi.Name);
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
}
// Copy each subdirectory using recursion.
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories())
{
DirectoryInfo nextTargetSubDir =
target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir);
}
}
below one is also good:
static public void CopyFolder( string sourceFolder, string destFolder )
{
if (!Directory.Exists( destFolder ))
Directory.CreateDirectory( destFolder );
string[] files = Directory.GetFiles( sourceFolder );
foreach (string file in files)
{
string name = Path.GetFileName( file );
string dest = Path.Combine( destFolder, name );
File.Copy( file, dest );
}
string[] folders = Directory.GetDirectories( sourceFolder );
foreach (string folder in folders)
{
string name = Path.GetFileName( folder );
string dest = Path.Combine( destFolder, name );
CopyFolder( folder, dest );
}
}
you can use this function also:
FileSystem.CopyDirectory(sourceDir, destDir);
FileSystem.CopyDirectory(sourceDir, destDir);
FileSystem.CopyDirectory is in a VB namespace and assembly, but that probably doesn't matter.
How to: Copy, Delete, and Move Files and Folders (C# Programming Guide)
http://msdn.microsoft.com/en-us/library/cc148994.aspx
C# Copy Folder Recursively
http://www.csharp411.com/c-copy-folder-recursively/
Here's an extension that will work in .NET 4.0+
var source = new DirectoryInfo(#"C:\Test");
var destination = new DirectoryInfo(#"E:\Test");
source.CopyTo(destination);
Include this file in your project
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace System.IO
{
public static class DirectoryInfoExtensions
{
public static void CopyTo(this DirectoryInfo source, DirectoryInfo target)
{
if (!target.Exists)
target.Create();
foreach (var file in source.GetFiles())
file.CopyTo(Path.Combine(target.FullName, file.Name), true);
foreach (var subdir in source.GetDirectories())
subdir.CopyTo(target.CreateSubdirectory(subdir.Name));
}
}
}
private String path;
public int copyAllContents(String destinationFolder, ProgressBar progressBar)
{
int countCopyFiles = 0;
if (!Directory.Exists(destinationFolder))
{ Directory.CreateDirectory(destinationFolder); }
String[] allFilesForCurrentFolder = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);
String[] subFoldersAllpath = Directory.GetDirectories(path);
for (int i = 0; i < allFilesForCurrentFolder.Length; i++)
{
try { File.Copy(allFilesForCurrentFolder[i], destinationFolder + "\\" + Path.GetFileName(allFilesForCurrentFolder[i])); countCopyFiles++; progressBar.Value++; }
catch (Exception ex) { Console.WriteLine(ex.Message.ToString()); }
}
if (subFoldersAllpath.Length == 0)
{ return allFilesForCurrentFolder.Length; };
for (int i = 0; i < subFoldersAllpath.Length; i++)
{
this.path = subFoldersAllpath[i];
String[] subFoldersAllpathLastFolder = subFoldersAllpath[i].Split('\\');
countCopyFiles += this.copyAllContents(destinationFolder + "\\" + subFoldersAllpathLastFolder[subFoldersAllpathLastFolder.Length - 1], progressBar);
}
return countCopyFiles;
}
Here's an approach that copies a directory recursively as an async function:
public static async Task CopyDirectoryAsync(string sourceDirectory, string destinationDirectory)
{
if (!Directory.Exists(destinationDirectory))
Directory.CreateDirectory(destinationDirectory);
foreach (var file in Directory.GetFiles(sourceDirectory))
{
var name = Path.GetFileName(file);
var dest = Path.Combine(destinationDirectory, name);
await CopyFileAsync(file, dest);
}
foreach (var subdir in Directory.GetDirectories(sourceDirectory))
{
var name = Path.GetFileName(subdir);
var dest = Path.Combine(destinationDirectory, name);
await CopyDirectoryAsync(subdir, dest);
}
}
public static async Task CopyFileAsync(string sourceFile, string destinationFile)
{
using (var sourceStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan))
using (var destinationStream = new FileStream(destinationFile, FileMode.CreateNew, FileAccess.Write, FileShare.None, 4096, FileOptions.Asynchronous | FileOptions.SequentialScan))
await sourceStream.CopyToAsync(destinationStream);
}
Related
static string mydir = #"C:\Boba\bin\Release\ZipTest";
static string zipfile = string.Concat(mydir, ".zip");
using (ZipStorer zip = ZipStorer.Create(zipfile))
{
zip.AddDirectory(ZipStorer.Compression.Deflate, mydir, zipfile);
}
But after I unpack the archive, folders appear
Dir: Boba -> bin > Release > ZipTest > Files...
How do I add only the ZipTest folder?
I tried to do it like this:
DirectoryInfo d = new DirectoryInfo(mydir);
zip.AddDirectory(ZipStorer.Compression.Deflate, Path.GetFileName(d.FullName), Path.GetFileName(d.FullName), comment);
A Zip archive is created, and inside a folder called ZipTestZipTest, inside there are files and an empty archive called .zip.
How to make it just ZipTest inside the archive?
And so that there is no empty archive in the ZipTest folder?
Try set 3rd argument (_pathnameInZip) for .AddDirectory as empty string:
string dir = #"C:\Boba\bin\Release\ZipTest";
string zipFile = string.Concat(dir, ".zip");
string comment = "My ZipTest";
using (ZipStorer zip = ZipStorer.Create(zipFile))
{
zip.AddDirectory(ZipStorer.Compression.Deflate, dir, string.Empty, comment);
}
If you need without an internal directory, then you can do this:
public static void PackToZipWithoutInternalDir(string dir, string zipout, string comment = "")
{
if (Directory.Exists(dir) && !string.IsNullOrWhiteSpace(dir) && !string.IsNullOrWhiteSpace(zipout))
{
try
{
using var zip = ZipStorer.Create(zipout, comment); // true for stream
zip.EncodeUTF8 = true; // Text encoding
zip.ForceDeflating = true; // Force file compression
foreach (string listDir in Directory.EnumerateDirectories(dir, "*", SearchOption.TopDirectoryOnly))
{
// Add folders with files to the archive
zip.AddDirectory(ZipStorer.Compression.Deflate, listDir, string.Empty);
}
foreach (string listFiles in Directory.EnumerateFiles(dir, "*.*", SearchOption.TopDirectoryOnly))
{
// Add residual files in the current directory to the archive.
zip.AddFile(ZipStorer.Compression.Deflate, listFiles, Path.GetFileName(listFiles));
}
}
catch (Exception ex) { Console.WriteLine(ex); }
}
}
Use:
namespace ZipStorerEx
{
using System;
using System.IO;
public static class Program
{
private static readonly string CurrDir = Environment.CurrentDirectory;
private static readonly string BeginDir = Path.Combine(CurrDir, "YouDir");
private static readonly string ZipOut = $"{BeginDir}.zip";
[STAThread]
public static void Main()
{
Console.Title = "ZipStorerEx";
PackToZipWithoutInternalDir(BeginDir, ZipOut, "It's Good");
Console.ReadKey();
}
}
}
I want get all files from an external storage folder(wall_e_imgs)..Here are codes-
public void getImages()
{
var path1 = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath.ToString();
string path = System.IO.Path.Combine(path1, "wall_e_imgs");
//var files= System.IO.Directory.GetFiles(Android.OS.Environment.ExternalStorageDirectory.ToString() + "wall_e_imgs");
//var files = System.IO.Directory.GetFiles(path);
//string path = Android.OS.Environment.ExternalStorageDirectory.ToString() + "/wall_e_imgs";
//File directory=new File(path);
Java.IO.File directory = new Java.IO.File(path);
Java.IO.File[] files = directory.ListFiles();//always count is 0 even though there are lot files there
foreach (var i in files)
{
FileInfo info = new FileInfo(i.Name);
if (info.Name.Contains("Wall_e"))
{
di.Add(new DownloadedImages { Path1 = info.DirectoryName, Name1 = info.FullName });
}
}
}
But it always give 0 files even though there are lot of files.
Try this
var folder = Android.OS.Environment.ExternalStorageDirectory + Java.IO.File.Separator + "yourfoldername";
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
var filesList = Directory.GetFiles(folder);
foreach (var file in filesList)
{
var filename = Path.GetFileName(file);
}
Try something like this:
// Use whatever folder path you want here, the special folder is just an example
string folderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "wall_e_imgs");
if (Directory.Exists(folderPath))
{
var files = Directory.EnumerateFiles(folderPath);
foreach (var file in files)
{
// Do your stuff
}
}
Please note that this uses the Directory class from System.IO, not Java.IO
ffilelist will contain a list of mp3 files in "/storage/emulated/0/Music/"
string phyle;
string ffilelist = "";
public void listfiles()
{
try
{
var path1 = "/storage/emulated/0/Music/";
var mp3Files = Directory.EnumerateFiles(path1, "*.mp3", SearchOption.AllDirectories);
foreach (string currentFile in mp3Files)
{
phyle = currentFile;
ffilelist = ffilelist + "\n" + phyle;
}
//playpath(phyle); // play the last file found
}
catch (Exception e9)
{
Toast.MakeText(ApplicationContext, "ut oh\n"+e9.Message , ToastLength.Long).Show();
}
}
I am trying to filter out the path C:\$Recycle.bin in my file enumeration. How can I do this?
var files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).OrderBy(p => p).ToList();
When I execute the above, I get the error below.
Additional information: Access to the path 'C:\$Recycle.Bin\S-1-5-21-1600837348-2291285090-976156579-500' is denied.
I also want to calc every file's md5. I have:
var mainDirectory = new DirectoryInfo("\\");
var files = GetDirectories(mainDirectory);
List<string> drives = new List<string>();
foreach (var file in files)
{
//Console.WriteLine(file.Name);
drives.Add(mainDirectory + file.Name);
}
MD5 md5 = MD5.Create();
foreach (string file in drives)
{
// hash path
string relativePath = file.Substring("\\".Length + 1);
byte[] pathBytes = Encoding.UTF8.GetBytes(relativePath.ToLower());
md5.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0);
// hash contents
try
{
byte[] contentBytes = File.ReadAllBytes(file);
md5.TransformBlock(contentBytes, 0, contentBytes.Length, contentBytes, 0);
md5.TransformFinalBlock(contentBytes, 0, contentBytes.Length);
}
catch(UnauthorizedAccessException)
{
continue;
}
catch
{
continue;
}
Console.WriteLine(BitConverter.ToString(md5.Hash).Replace("-", "").ToLower());
}
Console.ReadKey();
The following could do it for you, but it is a quick and dirty way, because it does not handle any exceptions. I did not regard any readability and it is not fully tested.
static void Main(string[] args)
{
var mainDirectory = new DirectoryInfo("C:\\");
var files = GetFiles(mainDirectory, ".");
foreach (var file in files)
{
Console.WriteLine(file.Name);
}
Console.ReadKey();
}
static IEnumerable<DirectoryInfo> GetDirectories(DirectoryInfo parentDirectory)
{
DirectoryInfo[] childDirectories = null;
try
{
childDirectories = parentDirectory.GetDirectories();
}
catch (Exception)
{
}
yield return parentDirectory;
if (childDirectories != null)
{
foreach (var childDirectory in childDirectories)
{
var childDirectories2 = GetDirectories(childDirectory);
foreach (var childDirectory2 in childDirectories2)
{
yield return childDirectory2;
}
}
}
}
static IEnumerable<FileInfo> GetFiles(DirectoryInfo parentDirectory,
string searchPattern)
{
var directories = GetDirectories(parentDirectory);
foreach (var directory in directories)
{
FileInfo[] files = null;
try
{
files = directory.GetFiles(searchPattern);
}
catch (Exception)
{
}
if (files != null)
{
foreach (var file in files)
{
yield return file;
}
}
}
}
I'm constructing a program to search all .xml inside a folder setted by user (Source folder) and copy all these files to another folder (Destination folder).
My program is able to search all XML within all sub folders from (Source folder), the result returns around 5000 files that are placed on a list, this list is worked later by a function, but he can only work with 31 files, then appears "not responding "and the debugger shows that the program is staying a long time in the execution.
Here is my code:
Button action:
private void btnCopiarSalvar_Click(object sender, EventArgs e)
{
foreach (string name in listFileNames)
{
if (readXML(name ))
{
tbArquivo.Text = name ; //Feedback textbox, tell the current filename
}
}
pbStatus.Increment(50);
cbFinal.Checked = true; //Feedback checkBox, to tell user that the task is over.
}
Function ReadXML
public bool readXML(string name)
{
//foreach (string nome in listaArquivos)
//{ //I tried to the foreach inside, but nothing Works.
try
{
string text = null;
string readBuffer = File.ReadAllText(name);
text = readBuffer.Aggregate(text, (current, b) => current + b);
var encoding = new ASCIIEncoding();
Byte[] textobytes = encoding.GetBytes(text);
if (!File.Exists(destino))
{
string destinoComNomeArquivo = destino + "\\" + Path.GetFileName(nome);
using (FileStream fs = File.Create(destinoComNomeArquivo))
{
foreach (byte textobyte in textobytes)
{
fs.WriteByte(textobyte);
pbProcess.PerformStep();
}
Console.WriteLine("Arquivo gravado " + Path.GetFileName(nome));
}
}
pbProcess.PerformStep();
}
catch (Exception e)
{
Console.WriteLine(e);
}
//}
return true;
}
Error: ContextSwitchDeadlock was detected.
Tried Solution: Disable Managed Debug Assistants.
After disabling the MDA, the programs still only read-copy 31 files (of 5k).
The first thing i recommand is ... don't do that kind of file copy! use the File.Copy function instead.
Try to use this code snipping from MSDN:
void DoCopy(string path)
{
var copytask = new Task(() =>
{
string destinoComNomeArquivo = #"C:\" + Path.GetFileName(path);
DirectoryCopy(path, destinoComNomeArquivo, false);
});
copytask.Start();
}
private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: "
+ sourceDirName);
}
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
var counter = 0;
var maxcounter = files.Count();
while (maxcounter < counter)
{
var item = files.ElementAt(counter).Name;
WriteAsnc(item);
counter++;
}
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
const int _maxwritingprocess = Environment.ProcessorCount;
int _currentwritingtasks;
void WriteAsnc(string filepath)
{
_currentwritingtasks++;
var task = Task.Factory.StartNew(() =>
{
XDocument doc = XDocument.Load(filepath);
doc.Elements().First().Add(new XAttribute("Attribute Name","Attribute Value"));
doc.Save(filepath);
_currentwritingtasks--;
});
if(_currentwritingtasks == _maxwritingprocess)
task.Wait();
_currentwritingtasks--;
}
The next point the ContextSwitchDeadlock is a Threading problem and i thing your pbProcess is the source. What does that Process do i don't see anything of that process and i don't thing it is Impotent for your copy
I need to copy multiple files from a directory using a textfile that doesnt contain complete info.
NCR.txt:
Red
target directory has in it:
red1.txt
red3.txt
red44.txt
dest directory needs to have:
red1.txt
red3.txt
red44.txt
My code:
System.IO.Directory.CreateDirectory(#"C:\nPrep\" + textBox1.Text + "\\red");
if (checkBox3.Checked)
{
String[] file_names = File.ReadAllLines(#"C:\NCR.txt");
foreach (string file_name in file_names)
{
string[] files = Directory.GetFiles(textBox2.Text, file_name + "*.txt");
foreach (string file in files)
System.IO.File.Copy(file, #"C:\nPrep\" + textBox1.Text + "\\red\\");
}
}
//FileInfo & DirectoryInfo are in System.IO
//This is something you should be able to tweak to your specific needs.
static void CopyFiles(DirectoryInfo source,
DirectoryInfo destination,
bool overwrite,
string searchPattern)
{
FileInfo[] files = source.GetFiles(searchPattern);
//this section is what's really important for your application.
foreach (FileInfo file in files)
{
file.CopyTo(destination.FullName + "\\" + file.Name, overwrite);
}
}
This version is more copy-paste ready:
static void Main(string[] args)
{
DirectoryInfo src = new DirectoryInfo(#"C:\temp");
DirectoryInfo dst = new DirectoryInfo(#"C:\temp3");
/*
* My example NCR.txt
* *.txt
* a.lbl
*/
CopyFiles(src, dst, true);
}
static void CopyFiles(DirectoryInfo source, DirectoryInfo destination, bool overwrite)
{
List<FileInfo> files = new List<FileInfo>();
string[] fileNames = File.ReadAllLines("C:\\NCR.txt");
foreach (string f in fileNames)
{
files.AddRange(source.GetFiles(f));
}
if (!destination.Exists)
destination.Create();
foreach (FileInfo file in files)
{
file.CopyTo(destination.FullName + #"\" + file.Name, overwrite);
}
}
All suggestions were great and thansk for all the advise but this was perfect:
if (checkBox3.Checked)
{
string[] lines = File.ReadAllLines(#"C:\NCR.txt");
foreach (string line in lines)
{
string[] files = Directory.GetFiles(textBox2.Text, line + "*.txt");
foreach (string file in files)
{
FileInfo file_info = new FileInfo(file);
File.Copy(file, #"C:\InPrep\" + textBox1.Text + "\\text\\" + file_info.Name);
}
}
}
string sourceDir = #"c:\";
string destDir = #"c:\TestDir";
var r = Directory.GetFiles(sourceDir, "red*.txt"); //Replace this part with your read from notepad file
foreach (var s in r)
{
var sourceFile = new FileInfo(s);
sourceFile.CopyTo(destDir + "\\" + s.Replace(sourceDir, string.Empty));
}