I have an issue with my code I can get it to copy all the files in a directory and it's subdirectories and I have got an if statement telling it to copy a file if the modified date is the same as today but it still copy's all the files I have searched on the internet for a solution and they all come up with vague answers that are similar to the doe I already have I have pasted the code below.
DirectoryInfo source = new DirectoryInfo(dlg.SelectedPath);
DirectoryInfo target = new DirectoryInfo(dlg2.SelectedPath);
DirectoryInfo dir = new DirectoryInfo(dlg.SelectedPath);
FileInfo[] fis = dir.GetFiles("*", SearchOption.AllDirectories);
foreach (FileInfo fi in fis)
{
if (fi.LastWriteTime.Date == DateTime.Today.Date)
{
FileInfo[] sourceFiles = source.GetFiles("*", SearchOption.AllDirectories);
foreach (FileInfo fc in sourceFiles)
if (fc.LastWriteTime.Date == DateTime.Today.Date)
for (int i = 0; i < sourceFiles.Length; ++i)
File.Copy(sourceFiles[i].FullName, target.FullName + "\\" + sourceFiles[i].Name, true);
}
}
any help will be appreciated
Shouldn't it be like this?
FileInfo[] fis = dir.GetFiles("*", SearchOption.AllDirectories);
foreach (FileInfo fi in fis)
{
if (fi.LastWriteTime.Date == DateTime.Today.Date)
{
File.Copy(fi.FullName, target.FullName + "\\" + fi.Name, true);
}
}
The thing is, right now, whenever you find a file that fulfills your condition, you copy all the files in the source folder to the target folder, which is wrong. You should only copy the files that you need.
The code above will only work for the files in the root folder, but it's easy to make it work for subfolders as well. Just make another function that finds all the subfolders in a folder and call the code above with each of the subfolders as parameters.
The precision of the DateTime on the FileSystem and in .net isn't the same.
Try Something like this:
if((Math.Abs((currentFile.LastWriteTime - DateTime.Today.Date).TotalMilliseconds) > tolerance){...}
As an alternative, you could use a LINQ query like the following:
DirectoryInfo source = new DirectoryInfo(dlg.SelectedPath);
DirectoryInfo target = new DirectoryInfo(dlg2.SelectedPath);
var files = source.GetFiles("*", SearchOption.AllDirectories).Where(file => file.LastWriteTime.Date.Equals(DateTime.Today.Date));
foreach (FileInfo file in files)
File.Copy(file.FullName, target.FullName + "\\" + file.Name, true);
i think you are missing indentation or parenthesis after the if statement, i think it's an empty if followed by the copy statement. do
if (date == date)
{
filecopy
}
Related
Suppose I forget the full path of a file on my computer, but I remember the filename and a segment of the path.
example:
my filename is test and the segment of the path that I sill remember is \test1\test2
So I would like to get the full path with c#, like this: C:\test1\test2\test3\test4\test.txt
Thanks in advance!
If the segment you know is at the start of the path, you can do something like
DirectoryInfo f = new DirectoryInfo(#"C:\test1\test2");
var results = f.GetFiles("test.txt", SearchOption.AllDirectories);
If not, I'm afraid that you have to do a full search on the computer, and check if the result path contains your fragment.
You can go through all the files on the drive and check whether they match what you want: (This will be slow and resource consuming.)
var files = Directory.GetFiles(#"C:\", "test.txt", SearchOption.AllDirectories)
.Where(s => s.Contains(#"\test1\test2\"));
foreach (var f in files)
{
Console.WriteLine(f);
}
Or you know the root directory in which you want to search, you can change it like this to be faster:
var files = Directory.GetFiles(#"C:\test1\test2", "test.txt", SearchOption.AllDirectories);
foreach (var f in files)
{
Console.WriteLine(f);
}
I have a curious problem in a C#-program.
I have some local folderpaths like
"C:\test\AB_Systems\ELEGANCE\CB-DOC\live\M7-091.249.99.XX.01\extobjects".
Now i want to search for PDF-files in the subfolder called "extobjects".
Unfortunately there are many subfolders in the folder "live", which got a subfolder called "extobjects", so i thought it would be better to use a wildcard in the searchpath like that:
"C:\test\AB_Systems\ELEGANCE\CB-DOC\live\*\extobjects"
But this doesn't work.
Is there a way do do this?
public static FileInfo[] findFile(String whereToSearch, String searchFor , String mode)
{
IEnumerable<FileInfo> files = null;
if (mode.Equals(""))
mode = "s";
if (searchFor.Equals(""))
searchFor = "*";
if (mode.Equals("r") || mode.Equals("recursive"))
{
DirectoryInfo dir = new DirectoryInfo(whereToSearch);
files = dir.EnumerateFiles(searchFor, searchOption: SearchOption.AllDirectories);
}
if (mode.Equals("s") || mode.Equals("specific"))
{
DirectoryInfo dir = new DirectoryInfo(whereToSearch);
files = dir.EnumerateFiles(searchFor, searchOption: SearchOption.TopDirectoryOnly);
}
if (files != null) return files.ToArray<FileInfo>();
else return null;
}
That's an example how to do it.
It's important to say that only the filename can contain a wildcard pattern like *. The Path can be given as where to start the search and by giving searchOption: searchOption.AllDirectories as an argument it will go through all sub-directories of the entry path.
You will receive an Array of FileInfo which objects that contain the the path and more information.
You can use Linq like this:
var files = Directory
.EnumerateDirectories(#"C:\test\AB_Systems\ELEGANCE\CB-DOC\live", "extobjects", SearchOption.AllDirectories)
.SelectMany(x => Directory.EnumerateFiles(x, "*pdf", SearchOption.TopDirectoryOnly))
.ToArray();
I'd choose a solution exactly what BugFinder proposed, you could optimize the following foreach-loop into a LINQ query if your .NET target supports it.
// Itterate subdirectories of the live folder
foreach (var subDir in Directory.GetDirectories(#"C:\test\AB_Systems\ELEGANCE\CB-DOC\live"))
{
// Check if path to extobjects exists
var extObjects = Path.Combine(subDir, "extobjects");
if (Directory.Exists(extObjects))
{
var pdfFiles = Directory.GetFiles(extObjects, "*").Where(x=>x.EndsWith(".pdf"));
// Do something with the pdf file paths
}
}
i am picking txt files from a folder in that i am ordering those file according to their respective modify date after ordering these files i've to read contents of each one by one. what will be the possible solution for this. cause i am not able convert FileInfo object to string following is the snippet.
in output : i want all files sorted according to modified date and want to read it one by one.
thanks
string sourcePath = #"C:\sample\*.log";
DirectoryInfo dir = new DirectoryInfo(sourcePath);
FileInfo[] files = dir.GetFiles(sourcePath).OrderBy(order => order.LastWriteTime).ToArray();
foreach (var item in files)
{
listBox1.items.Add(item)
}
Use File.ReadAllText and FileInfo.FullName property to get the path :
listBox1.items.Add(File.ReadAllText(item.FullName));
If you are only looking to get FileName of the file then use FileInfo.Name property like:
listBox1.items.Add(item.Name);
If you are looking to get file path then use FileInfo.FullName like:
listBox1.items.Add(item.FullName);
use the method File.ReadAllText to read each file.
string sourcePath = #"C:\sample\*.log";
DirectoryInfo dir = new DirectoryInfo(sourcePath);
FileInfo[] files = dir.GetFiles(sourcePath).OrderBy(order => order.LastWriteTime).ToArray();
foreach (var item in files)
{
string filecontent = File.ReadAllText(item.FullName);
//do your job here
......
listBox1.items.Add(item.Name);
}
Trying to convert some VB to C#... (learning C#, too).
I have some code that loops through files in a directory and retrieves their file information. I have this originally in VB, but am trying to learn C#, and the online convertors don't give me code that will pass .net 2.0.
Here is the error:
Type and identifier are both required in a foreach statement
Here is the code I have:
DirectoryInfo dirInfo = new DirectoryInfo(currentDir);
FileInfo[] files = null;
files = dirInfo.GetFiles();
FileInfo f = default(FileInfo);
foreach (f in files) { ...
}
I tried putting foreach(FileInfo f... but it gives me a different error:
A local variable named 'f' cannot be declared in this scope because it would give a different meaning to 'f', which is already used in a 'parent or current' scope to denote something else
How do I fix it?
DirectoryInfo dirInfo = new DirectoryInfo(currentDir);
FileInfo[] files = null;
files = dirInfo.GetFiles();
// I removed the declaration of f here to prevent the name collision.
foreach (FileInfo f in files)
{ ...
}
Here is a simpler version of the code:
DirectoryInfo dirInfo = new DirectoryInfo(currentDir);
foreach (FileInfo f in dirInfo.GetFiles())
{
}
Here's where it looks like you're going wrong:
FileInfo f = default(FileInfo);
foreach (f in files) { ...
}
You are defining f outside of the loop, and then attempting to define it within the loop.
If you need the default to be f, try this:
FileInfo f = default(FileInfo);
foreach (FileInfo file in files)
{
relevant code here
}
Otherwise delete the statement declaring the variable "f"
You should provide type of variable used inside loop. In your case it will be FileInfo. But with C# 3.0 or later you can just write var and compiler will infer type for you:
foreach (FileInfo f in files)
{
// ...
}
Read more about foreach statement here.
Complete solution (you don't need to initialize iteration variable and array of files):
DirectoryInfo dir = new DirectoryInfo(currentDir);
foreach (FileInfo file in dir.GetFiles())
{
// use file
}
This should work:
DirectoryInfo dirInfo = new DirectoryInfo(currentDir);
FileInfo[] files = null;
files = dirInfo.GetFiles();
foreach (FileInfo f in files)
{
}
Edit:
This would be cleaner, in my opinion:
foreach (FileInfo f in new DirectoryInfo(currentDir).GetFiles())
{
}
I am using VSTS 2008 + C# + .Net 3.0. I want to enumerate all files in a directory by creation time, i.e. files created more recently will be enumarate at first, older files will be enumerated at last. Any ideas how to implment this?
Something like that
System.IO.FileInfo[] array = new System.IO.DirectoryInfo("directory_path").GetFiles();
Array.Sort(array, delegate(System.IO.FileInfo f1, System.IO.FileInfo f2)
{
return f2.CreationTimeUtc.CompareTo(f1.CreationTimeUtc);
});
I would probably use LINQ and a list... something like this should work:
DirectoryInfo di = new DirectoryInfo("YourPath");
List<FileInfo> files = di.GetFiles().OrderBy(f => f.CreationTime).ToList();
foreach (FileInfo file in files)
{
//do something
}
Try somithing like this:
DirectoryInfo di = new DirectoryInfo("path to folder");
FileInfo[] files = di.GetFiles();
IOrderedEnumerable<FileInfo> enumerable = files.OrderBy(f => f.CreationTime);
foreach (FileInfo info in enumerable)
{
// do stuff...
}
EDIT: updated, here's a non-LINQ solution
FileInfo[] files = new DirectoryInfo("directory").GetFiles();
Array.Sort(files, delegate(FileInfo f1, FileInfo f2) {
return f2.CreationTime.CompareTo(f1.CreationTime);
});
The above will sort by latest to oldest. To sort by oldest to latest change the delegate to: return f1.CreationTime.CompareTo(f2.CreationTime);
LINQ solution:
FileInfo[] files = new DirectoryInfo("directory").GetFiles();
var results = files.OrderByDescending(file => file.CreationTime);
Use OrderByDescending to sort by most recent CreationTime, otherwise use OrderBy to sort from oldest to newest CreationTime.
DirectoryInfo baseFolder=new DirectoryInfo("folderName");
FileInfo[] files=baseFolder.GetFiles("");
for(int i=1; i<=files.Length;i++)
for(int j=1; j<files.Length;j++)
{
if(files[j].CreationTime > files[j+1].CreationTime)
{
FileInfo f = files[j];
files[j] = files[j+1];
files[j+1] = f;
}
}