I have excel list with file names that I want to move from one folder to another. And I can not just copy paste the files from one folder to another since there are allot of files that do not match the excel list.
private static void CopyPaste()
{
var pstFileFolder = "C:/Users/chnikos/Desktop/Test/";
//var searchPattern = "HelloWorld.docx"+"Test.docx";
string[] test = { "HelloWorld.docx", "Test.docx" };
var soruceFolder = "C:/Users/chnikos/Desktop/CopyTest/";
// Searches the directory for *.pst
foreach (var file in Directory.GetFiles(pstFileFolder, test.ToString()))
{
// Exposes file information like Name
var theFileInfo = new FileInfo(file);
var destination = soruceFolder + theFileInfo.Name;
File.Move(file, destination);
}
}
}
I have tried several things but I still think that with a array it would be the easiest way to do it(correct me if I am wrong).
The issue that I face right now is that it can not find any files (there are files under this name.
You can enumerate the files in the directory by using Directory.EnumerateFiles and use a linq expression to check if the file is contained in you string array.
Directory.EnumerateFiles(pstFileFolder).Where (d => test.Contains(Path.GetFileName(d)));
So your foreach would look like
this
foreach (var file in Directory.EnumerateFiles(pstFileFolder).Where (d => test.Contains(Path.GetFileName(d)))
{
// Exposes file information like Name
var theFileInfo = new FileInfo(file);
var destination = soruceFolder + theFileInfo.Name;
File.Move(file, destination);
}
Actually no, this will not search the directory for pst files. Either build the path yourself using Path.Combine and then iterate over the string-array, or use your approach. With the code above, you need to update the filter, because it will not find any file when given a string[].ToString (). This should do:
Directory.GetFiles (pstFileFolder, "*.pst")
Alternatively, you can iterate over all files without a filter and compare the filenames to your string-array. For this, a List<string> would be a better way. Just iterate over the files like you're doing and then check if the List contains the file via List.Contains.
foreach (var file in Directory.GetFiles (pstFileFolder))
{
// Exposes file information like Name
var theFileInfo = new FileInfo(file);
// Here, either iterate over the string array or use a List
if (!nameList.Contains (theFileInfo.Name)) continue;
var destination = soruceFolder + theFileInfo.Name;
File.Move(file, destination);
}
I think you need this
var pstFileFolder = "C:/Users/chnikos/Desktop/Test/";
//var searchPattern = "HelloWorld.docx"+"Test.docx";
string[] test = { "HelloWorld.docx", "Test.docx" };
var soruceFolder = "C:/Users/chnikos/Desktop/CopyTest/";
// Searches the directory for *.pst
foreach (var file in test)
{
// Exposes file information like Name
var theFileInfo = new FileInfo(file);
var source = Path.Combine(soruceFolder, theFileInfo.Name);
var destination = Path.Combine(pstFileFolder, file);
if (File.Exists(source))
File.Move(file, destination);
}
Related
I have this method that searches all files and folders in "C:\Sharing".
string[] fileArray = Directory.GetFiles(#"C:\Sharing", "*.*", SearchOption.AllDirectories);
And foreach shows me full path of each file. Great. However, since these are in a directory called "Sharing", I want to check and add files that are like
C:\Sharing\Jerry2022\wedding.jpg (array: 'wedding.jpg', 'Jerry2022')
C:\Sharing\snapshot.jpg (array: 'snapshot.jpg')
C:\Sharing\Newsletter\cover-june.webp (array: 'cover-june.webp', 'Newsletter')
So as you can see, I want to add file and subdirectory name to a string array or List, doesnt matter. Excluding "Sharing".
How can I split the results? I know I can use Substring and LastIndexOf("\") + 1 and separate the ending '' but I'm not sure how to match up the filename with the subdir name too.
Any help is appreciated
You can use DirectoryInfo to get the information you want:
C#:
var directoryInfo = new DirectoryInfo(#"C:\Sharing");
if (directoryInfo.Exists)
{
foreach (var fileInfo in directoryInfo.GetFiles("*.*", SearchOption.AllDirectories))
{
var fileName = fileInfo.Name;
Console.WriteLine(fileName);
var directoryName = fileInfo.DirectoryName;
// you can use split to get the directory name array
Console.WriteLine(directoryName);
}
}
I found an other way, use Uri for this scenario:
C#:
string[] fileArray = Directory.GetFiles(#"C:\Sharing", "*.*", SearchOption.AllDirectories);
foreach (var s in fileArray)
{
var uri = new Uri(s);
var uriSegments = uri.Segments.ToArray();
}
You will see each part of the full path, but you may need to use .Trim('/') for each part. Then you can use string.Equals to get directories which you want.
You could split the results using Split
But of course you can also work with FileInfo instead
I have 2 directories ..I need to check that in two directories the files exist is same or not..if there is difference in files then move that files from first directory to second directoy..how can i implement?
Something like this?
private void CopyMissedFiles(string source, string destination)
{
var sourceDir = new DirectoryInfo(source);
var destinationDir = new DirectoryInfo(destination);
var sourceFiles = sourceDir.GetFiles();
var destinationFiles = destinationDir.GetFiles();
foreach (var file in sourceFiles.Where(x => destinationFiles.All(y => y.Name != x.Name)))
{
file.CopyTo(Path.Combine(destinationDir.FullName, file.Name));
}
}
Update:
if you need to compare the file content, you can use MD5 hash to do that. Here is the description, how to calculate the hash Calculate MD5 checksum for a file
I have a FileInfo[] fileInfos class and I want to use it inside a function to return the files inside a folder to be executed in a copy function
FileInfo[] fileInfos = new DirectoryInfo(FolderLocation).GetFiles("*.*", SearchOption.TopDirectoryOnly);
IEnumerable<FileInfo> files = fileInfos.Where((f) => f.CreationTime <= FileDateLessThan);
I want to use it inside this function
string[] filePaths = Directory.GetFiles("Your Path");
foreach (var filename in filePaths)
{
string file = filename.ToString();
//Do your job with "file"
string str = "Your Destination"+file.ToString(),=.Replace("Your Path");
if (!File.Exists(str))
{
File.Copy(file , str);
}
}
I tried to use it but I get the error FileInfo is a type
if (ExecutableAction == "COPY")
{
string[] filePaths = Directory.GetFiles(FileInfo[] fileInfos);
foreach (var filename in filePaths)
{
string file = filename.ToString();
//Do your job with "file"
string str = TargetfolderLocation + file.ToString().Replace(FileInfo[] fileInfos);
if (!File.Exists(str))
{
File.Copy(file, str);
}
}
}
What is the proper way to reference the FileInfo type in my function
Here's some points to consider.
Get the files
You can replace the first block of code with:
var files = new DirectoryInfo(FolderLocation).EnumerateFiles("*.*", SearchOption.TopDirectoryOnly)
.Where(f => f.CreationTime <= FileDateLessThan);
To return an IEnumerable<FileInfo> assigned to the files variable in a single query instead of two.
Note that, the FileInfo class encapsulates properties like the Name property which returns the name of the file including the extension, and the FullName property which returns the path of the file including it's Name.
Also, the FileInfo class contains methods like CopyTo and MoveTo to copy/move a file to a different destination. Meaning, no need to use methods from another class (like File.Copy, and File.Move) to perform these operations.
Copy them
As I understand, you want to copy files to a new destination. So, all what you need to do:
//For example:
var destination = #"c:\temp\";
files.ToList().ForEach(f =>
f.CopyTo(Path.Combine(destination, f.Name), true)); //true to overwrite a file with the
//same name in the destination if any.
Or, to copy the file only if it does not exist in the destination:
files.ToList().ForEach(f =>
{
var s = Path.Combine(destination, f.Name);
if (!File.Exists(s))
f.CopyTo(s);
});
Or without using the File class:
files.Where(x => new FileInfo(Path.Combine(destination, x.Name)).Exists == false)
.ToList().ForEach(f => f.CopyTo(Path.Combine(destination, f.Name)));
Note the Path.Combine function which is used here - instead of a string concatenation - to create a valid path.
All-in-One
You can combine everything in just:
private void TheCaller()
{
//..
//..
new DirectoryInfo(FolderLocation).EnumerateFiles("*.*", SearchOption.TopDirectoryOnly)
.Where(f => f.CreationTime <= FileDateLessThan &&
!File.Exists(Path.Combine(destination, f.Name)))
.ToList().ForEach(f => f.CopyTo(Path.Combine(destination, f.Name)));
}
Last Stop
The Directory.GetFiles(..) function returns a string array so no need to do string file = filename.ToString(); since the filename is already of string type.
You should instantiate an object of a Type to use it and not use a Type as an instance.
That's it all.
Would like to find a better way
(In terms of readability, performance or maybe the length of the code?)
to do the following, like func<>? any other way will do.
As you can see from the code, its trying to grab the matching files in DatafilePath, and check if those files with matching pattern exists in all matching directories of the date of today in the path of _checkFilePath.
e.g.
if I have two files c:\abc\abc_1_2_3_4_12345.csv and c:\abc\abc_1_2_3_4_34567.csv in the datafilePath,
I would like to check if two those files has matching patterns '12345' and '34567' exists all the directories in c:\def such as c:\def\2019-10-25_123 and c:\def\2019-10-25_124.
Thanks guys.
files = Directory.GetFiles(DataFilePath, FilePattern);
var archiveDirs = Directory.GetDirectories(_checkFilePath + "archive","*",SearchOption.AllDirectories).Where(x => x.Contains(string.Format("{0:yyyy-MM-dd}", DateTime.Now)));
var filesToProcess = new List<string>();
foreach (var archiveDirStr in archiveDirs)
{
foreach (var file in files)
{
var key = file.Split('_')[5];
var contactFile = Directory.GetFiles(archiveDirStr, "*" + key + "*").FirstOrDefault();
if (contactFile != null)
{
filesToProcess.Add(file);
}
}
}
files = filesToProcess.ToArray();
How to exclude certain file type when getting files from a directory?
I tried
var files = Directory.GetFiles(jobDir);
But it seems that this function can only choose the file types you want to include, not exclude.
You should filter these files yourself, you can write something like this:
var files = Directory.GetFiles(jobDir).Where(name => !name.EndsWith(".xml"));
I know, this a old request, but about me it's always important.
if you want exlude a list of file extension: (based on https://stackoverflow.com/a/19961761/1970301)
var exts = new[] { ".mp3", ".jpg" };
public IEnumerable<string> FilterFiles(string path, params string[] exts) {
return
Directory
.GetFiles(path)
.Where(file => !exts.Any(x => file.EndsWith(x, StringComparison.OrdinalIgnoreCase)));
}
You could try something like this:
var allFiles = Directory.GetFiles(#"C:\Path\", "");
var filesToExclude = Directory.GetFiles(#"C:\Path\", "*.txt");
var wantedFiles = allFiles.Except(filesToExclude);
I guess you can use lambda expression
var files = Array.FindAll(Directory.GetFiles(jobDir), x => !x.EndWith(".myext"))
You can try this,
var directoryInfo = new DirectoryInfo("C:\YourPath");
var filesInfo = directoryInfo.GetFiles().Where(x => x.Extension != ".pdb");
Afaik there is no way to specify the exclude patterns.
You have to do it manually, like:
string[] files = Directory.GetFiles(myDir);
foreach(string fileName in files)
{
DoSomething(fileName);
}
This is my version on the answers I read above
List<FileInfo> fileInfoList = ((DirectoryInfo)new DirectoryInfo(myPath)).GetFiles(fileNameOnly + "*").Where(x => !x.Name.EndsWith(".pdf")).ToList<FileInfo>();
I came across this looking for a method to do this where the exclusion could use the search pattern rules and not just EndWith type logic.
e.g. Search pattern wildcard specifier matches:
* (asterisk) Zero or more characters in that position.
? (question mark) Zero or one character in that position.
This could be used for the above as follows.
string dir = #"C:\Temp";
var items = Directory.GetFiles(dir, "*.*").Except(Directory.GetFiles(dir, "*.xml"));
Or to exclude items that would otherwise be included.
string dir = #"C:\Temp";
var items = Directory.GetFiles(dir, "*.txt").Except(Directory.GetFiles(dir, "*HOLD*.txt"));
i used that
Directory.GetFiles(PATH, "*.dll"))
and the PATH is:
public static string _PATH = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);