So I want to log what happens when I backup files but I'm not sure how to make it work for files in subdirectories aswell.
Right now I have this code that works for all files in the selected directory but doesn't work for subdirectory files
private void LogBackup(string sourceDirName, string destDirName)
{
List<string> lines = new List<string>();
string logDestination = this.tbox_LogFiles.Text;
string dateString = DateTime.Now.ToString("MM-dd-yyyy_H.mm.ss");
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
lines.Add("FILES TO COPY:");
lines.Add("--------------");
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files
.Where(f => !extensionsToSkip.Contains(f.Extension) && !filesToSkip.Contains(f.FullName)).ToList())
{
string desttemppath = Path.Combine(destDirName, file.Name);
string sourcetemppath = Path.Combine(sourceDirName, file.Name);
lines.Add("SOURCE FILE:");
lines.Add(sourcetemppath);
lines.Add("DESTINATION FILE:");
lines.Add(desttemppath);
lines.Add("");
}
foreach (DirectoryInfo subdir in dirs
.Where(f => !foldersToSkip.Contains(f.FullName)))
{
//NOT SURE WHAT TO WRITE HERE
}
using (StreamWriter writer = new StreamWriter(logDestination + #"\LOG " + dateString + ".txt"))
{
foreach (string line in lines)
{
writer.WriteLine(line);
}
}
}
Any ideas please?
Include the SearchOption.AllDirectories and you will get all sub directories:
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories("*", SearchOption.AllDirectories);
when you now loop through the directories, you will have also the first level of subdirectories and for each directory just get the files that it contains
foreach (DirectoryInfo subdir in dirs)
{
FileInfo[] files = subdir.GetFiles();
......
Related
so i have a listview that displays the filename of the text file thats fine
the problem is foreach textfile i have so say a file is called 8133.txt it has a image file to so 8133.jpg
i want that to match in my listview to the correct textfile
DirectoryInfo di = new DirectoryInfo("C:\\OmGRhys Student System Files - 2019\\");
FileInfo[] files = di.GetFiles("*.txt");
foreach (FileInfo f in files)
{
foreach (string imageFileName in Directory.GetFiles(path, "*.jpg"))
{
listView1.Items.Add(new ListViewItem(new string[] { f.Name, imageFileName }));
}
}
so..
and to keep that pattern for everyfile in the directorys
all textfiles and image files are in the same directory
Try this:
DirectoryInfo di = new DirectoryInfo("C:\\OmGRhys Student System Files - 2019\\");
FileInfo[] files = di.GetFiles("*.txt");
foreach (FileInfo f in files)
{
string imgName = Path.GetFileNameWithoutExtension(f.FullName) + ".jpg";
string imgFile = Path.Combine(di.FullName, imgName);
if (File.Exists(imgFile))
listView1.Items.Add(new ListViewItem(new string[] { f.Name, imgFile }));
}
One Question about coding (Visual Studio C# WindowsformApplication) There have Two folder: (Source and Target) and I build 1 button "Copy".
In "Source" folder have random folders such as "20190401", "20190402", "20190403", "20180401", "20170401" and "20160401". Every these folders have [10] .txt files. What is the coding if I only want to copy all "201904**" folders with [3] .txt files inside it to "Target" folder? Here is my code for now.
Code
** private void button1_Click
{
string FROM_DIR = "C:/Users/5004117928/Desktop/Source";
string TO_DIR = "C:/Users/5004117928/Desktop/Target/";
DirectoryInfo diCopyForm = new DirectoryInfo(FROM_DIR);
DirectoryInfo[] fiDiskfiles = diCopyForm.GetDirectories();
string directname = "201904";
string filename = ".txt";
foreach (DirectoryInfo newfile in fiDiskfiles)
{
try
{
if (newfile.Name == "2019")
{
foreach (DirectoryInfo direc in newfile.GetDirectories())
if (direc.Name.StartsWith(directname))
{
int count = 0;
foreach (FileInfo file in direc.GetFiles())
{
if (file.Name.EndsWith(filename))
{
count++;
}
}
if (count == 3)
{
DirectoryCopy(direc.FullName,Path.Combine(TO_DIR,direc.Name), true);
count = 0;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
MessageBox.Show("success");
}
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);
}
}
}**
I expect after I click a button,
output is automatically copy all folders Name Start With "201904**" with [3] text files inside from "Source" folder to "target" folder.
I reckon you can search the directory with names directly using linq and can copy the sub folders/files inside it like below. It will give you the flexibility of filtering folders/files/skipping/taking n folders/files
string FROM_DIR = "C:/Users/5004117928/Desktop/Source";
string TO_DIR = "C:/Users/5004117928/Desktop/Target/";
string searchText = "201904";
string extension = "txt";
IEnumerable<string> dirs = Directory.EnumerateDirectories(FROM_DIR, "*", SearchOption.AllDirectories)
.Where(dirPath=>Path.GetFileName(dirPath.TrimEnd(Path.DirectorySeparatorChar)).StartsWith(searchText));
foreach (string dir in dirs)
{
string destDirPath = dir.Replace(FROM_DIR, TO_DIR);
if (!Directory.Exists(destDirPath))
Directory.CreateDirectory(destDirPath);
//Copy all the files & Replaces any files with the same name
foreach (string newPath in Directory.EnumerateFiles(dir, string.format("*.{0}",extension),
SearchOption.AllDirectories))// Here you can skip/take n files if u need
File.Copy(newPath, newPath.Replace(FROM_DIR, TO_DIR), true);
}
Have tested with sub folders and files inside source folder as well. Hope it helps.
In my project I have to move the files in Main Folder Which locate in Sub-folders. the Below code move the First and second sub-folder files only. How can I move all the sub folders file to main folder.
Calling function -
MoveFilesToMain(#"F:\Test\New folder", #"F:\Test");
Function -
public static void MoveFilesToMain(string sourceDirName, string destDirName)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
File.Move(Path.Combine(sourceDirName, file.Name), Path.Combine(destDirName, file.Name));
}
foreach (DirectoryInfo subdir in dirs)
{
FileInfo[] files1 = subdir.GetFiles();
foreach (FileInfo file in files1)
{
File.Move(Path.Combine(subdir.FullName, file.Name), Path.Combine(destDirName, file.Name));
}
}
}
Below marked folders files are not moved.
a little bit of recursion should do the trick.
basically for a given source dir, we copy the files into the dest dir. then iterate through every sub dir in the source dir and repeat the process recursively.
public static void MoveFilesToMain(string sourceDirName, string destDirName)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
FileInfo[] files = dir.GetFiles();
if (files.Length == 0 && dirs.Length == 0)
{
Directory.Delete(sourceDirName, false);
return;
}
foreach (FileInfo file in files)
{
File.Move(Path.Combine(sourceDirName, file.Name), Path.Combine(destDirName, file.Name));
}
foreach (DirectoryInfo subdir in dirs)
{
MoveFilesToMain(subdir.FullName, destDirName)
}
}
Try this:
DirectoryInfo[] dirs = dir.GetDirectories("*",SearchOption.AllDirectories);
How to modify the code to copy and files in subdirectoryes of tempDownloadFolder?
private void moveFiles()
{
DirectoryInfo di = new DirectoryInfo(tempDownloadFolder);
FileInfo[] files = di.GetFiles();
foreach (FileInfo fi in files)
{
if (fi.Name != downloadFile)
File.Copy(tempDownloadFolder + fi.Name, destinationFolder + fi.Name, true);
}
}
You need to do a recursive search.
very rough example:
private void copyFiles(string filePath)
{
DirectoryInfo di = new DirectoryInfo(filePath);
FileInfo[] files = di.GetFiles();
foreach (FileInfo fi in files)
{
// test if fi is a directory
// if so call copyFiles(fi.FullName) again
// else execute the following
if (fi.Name != downloadFile) File.Copy(filePath+ fi.Name, destinationFolder + fi.Name, true);
}
}
If you want files of all subdirectories use the SearchOption parameter:
DirectoryInfo di = new DirectoryInfo(tempDownloadFolder);
di.GetFiles("*.*", SearchOption.AllDirectories);
FileInfo[] files = di.GetFiles();
foreach (FileInfo fi in files)
{
if (fi.Name != downloadFile)
File.Copy(tempDownloadFolder + fi.Name, destinationFolder + fi.Name, true);
}
Replace the File.Copy line by
File.Copy(fi.FullName, Path.Combine(destinationFolder, fi.Name), true);
Just find working solution here:
http://www.codeproject.com/Articles/3210/Function-to-copy-a-directory-to-another-place-noth?msg=4571843#xx4571843xx
Well I like this nice piece of code right here it seems to work awesomely but I can't seem to add any more directories to it
DirectoryInfo dir = new DirectoryInfo(#"C:\temp");
foreach(FileInfo files in dir.GetFiles())
{
files.Delete();
}
foreach (DirectoryInfo dirs in dir.GetDirectories())
{
dirs.Delete(true);
}
I would also like to add in special folders as well like History and cookies and such how would I go about doing that (I would like to include at least 4-5 different folders)
Perhaps something like this would help. I did not test it.
public void DeleteDirectoryFolders(DirectoryInfo dirInfo){
foreach (DirectoryInfo dirs in dirInfo.GetDirectories())
{
dirs.Delete(true);
}
}
public void DeleteDirectoryFiles(DirectoryInfo dirInfo) {
foreach(FileInfo files in dirInfo.GetFiles())
{
files.Delete();
}
}
public void DeleteDirectoryFilesAndFolders(string dirName) {
DirectoryInfo dir = new DirectoryInfo(dirName);
DeleteDirectoryFiles(dir)
DeleteDirectoryFolders(dir)
}
public void main() {
List<string> DirectoriesToDelete;
DirectoriesToDelete.add("c:\temp");
DirectoriesToDelete.add("c:\temp1");
DirectoriesToDelete.add("c:\temp2");
DirectoriesToDelete.add("c:\temp3");
foreach (string dirName in DirectoriesToDelete) {
DeleteDirectoryFilesAndFolders(dirName);
}
}
Here's a recursive function that will delete all files in a given directory and navigate down the directory structure. A pattern string can be supplied to only work with files of a given extension, as per your comment to another answer.
Action<string,string> fileDeleter = null;
fileDeleter = (directoryPath, pattern) =>
{
string[] files;
if (!string.IsNullOrEmpty(pattern))
files = Directory.GetFiles(directoryPath, pattern);
else
files = Directory.GetFiles(directoryPath);
foreach (string file in files)
{
File.Delete(file);
}
string[] directories = Directory.GetDirectories(directoryPath);
foreach (string dir in directories)
fileDeleter(dir, pattern);
};
string path = #"C:\some_folder\";
fileDeleter(path, "*.bmp");
Directories are otherwise left alone, and this can obviously be used with an array or list of strings to work with multiple initial directory paths.
Here is the same code rewritten as a standard function, also with the recursion as a parameter option.
public void DeleteFilesFromDirectory(string directoryPath, string pattern, bool includeSubdirectories)
{
string[] files;
if (!string.IsNullOrEmpty(pattern))
files = Directory.GetFiles(directoryPath, pattern);
else
files = Directory.GetFiles(directoryPath);
foreach (string file in files)
{
File.Delete(file);
}
if (includeSubdirectories)
{
string[] directories = Directory.GetDirectories(directoryPath);
foreach (string dir in directories)
DeleteFilesFromDirectory(dir, pattern, includeSubdirectories);
}
}