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;
}
}
Related
So I have a folder with some imagens in many extensions like .ico, .png, .jpg, etc. and I've populated it into a comboBox using this code:
string caminho = #"C:\Users\User1\Desktop\Test\";
DirectoryInfo dir = new DirectoryInfo(caminho);
FileInfo[] fi = dir.GetFiles();
foreach (var ficheiro in fi)
{
string caminhoF = caminho + ficheiro.ToString();
string extension = Path.GetExtension(caminhoF);
comboBox1.Items.Add(extension);
}
The code is getting all the existing extensions in this path and put it on the comboBox, but it displays like this:
.ico
.ico
.ico
.png
.png
.jpg
.jpg
and I want to simply display each one of the existing extensions like grouping them.
Could you help me with that?
You can get the file extension from the FileInfo. You can also use Linq Distinct() to get unique extensions.
string caminho = #"C:\Users\User1\Desktop\Test\";
DirectoryInfo dir = new DirectoryInfo(caminho);
var extensions = dir.GetFiles().Select(fi => fi.Extension).Distinct();
foreach (var extension in extensions) {
comboBox1.Items.Add(extension);
}
Ok, I was to find a solution for it. Here it is the code:
string caminho = #"C:\Users\User1\Desktop\Test\";
DirectoryInfo dir = new DirectoryInfo(caminho);
FileInfo[] fi = dir.GetFiles();
foreach (var ficheiro in fi)
{
string caminhoF = caminho + ficheiro.ToString();
string extension = Path.GetExtension(caminhoF);
if (!comboBox1.Items.Contains(extension))
{
comboBox1.Items.Add(extension);
}
}
LINQ-to-Objects makes this easy. LINQ is similar to SQL but allows chaining transformations.
var comboBox1 = new ComboBox();
var caminho = #"C:\Users\User1\Desktop\Test\";
var dir = new DirectoryInfo(caminho);
var extensions = dir.GetFiles()
.Select(fi => fi.Extension)
.OrderBy(ext => ext, StringComparer.CurrentCulture)
.Distinct(StringComparer.CurrentCultureIgnoreCase)
.ToArray();
comboBox1.Items.AddRange(extensions);
Here are the rough steps:
Scan your folder to find out what files it contains.
Extract the file extension from each file you find.
Using a data structure that stores only unique entries, add extensions that you find to be new to the structure.
Iterate over the data structure to populate your combobox.
The part that you need is to find a data structure that helps you store unique values.
HashSet<T> has your back here: it allows quick lookups to determine set membership ("does the set already contain some element x?").
string caminho = #"C:\Users\User1\Desktop\Test\";
DirectoryInfo dir = new DirectoryInfo(caminho);
FileInfo[] fi = dir.GetFiles();
HashSet<string> extensions = new HashSet<string>;
foreach (var ficheiro in fi)
{
string caminhoF = caminho + ficheiro.ToString();
string extension = Path.GetExtension(caminhoF);
// If the set does not contain this extension, it'll be added and
// `Add()` will return true. Otherwise, it will do nothing and `Add()`
// will return false.
extensions.Add( extension );
}
foreach( var extension in extensions ) {
comboBox1.Items.Add(extension);
}
I have been working on a program that requires a different approach to finish a job using try and catch nested within another try/catch.
For this purpose I have had to create a set of files as strings and then converted them to FileInfo.
IEnumerable<string> paths = null;
foreach (String fil in paths)
FileInfo h = new FileInfo(fil);
So That wasn't so difficult, I require FileInfo to be in the form of a FileInfo[] array to continue the program however.
System.IO.FileInfo[] files = null;
Simply put, what is the best method to convert one type to the other, either directly from the string of from the converted FileInfo into a FileInfo array (FileInfo[])?
Yeah or create a single-item array:
FileInfo[] files = new FileInfo[] { info };
Why not directly?
paths.Select(p => new FileInfo(p)).ToArray();
Use:
var result = paths.Select(p => new FileInfo(p)).ToArray();
You could just use Linq select to create your FileInfo[]
IEnumerable<string> paths = null; // assuming you are going to fill this with filenames
FileInfo[] fileInfos = paths.Select(p => new FileInfo(p)).ToArray();
I have two folders : FolderA and FolderB
I want to delete the files in FolderA which also exist in FolderB. (i.e. Common files will be deleted from folderA)
How can I do this most efficiently in C#? (That's a critical point in the project and it has to be as efficient as possible )
Thanx
This is easy, readable and also efficient:
var common = from f1 in Directory.EnumerateFiles(folderA, "*.*", SearchOption.AllDirectories)
join f2 in Directory.EnumerateFiles(folderB, "*.*", SearchOption.AllDirectories)
on Path.GetFileName(f1) equals Path.GetFileName(f2)
select f1;
foreach (string file in common)
{
File.Delete(file);
}
Assuming that you just want to compare the file names (and extension).
You can do this with the help of LINQ. See here.
If you only want to compare file names, here is how you can do it, I did a quick test of this code and it works:
string pathA = #"C:\New FolderA";
string pathB = #"C:\New FolderB";
var filesA = Directory.GetFiles(pathA).Select(path => Path.GetFileName(path));
var filesB = Directory.GetFiles(pathB).Select(path => Path.GetFileName(path));
var toBeDeleted = filesA.Intersect(filesB);
foreach (string filename in toBeDeleted)
File.Delete(Path.Combine(pathA, filename));
string[] FolderAFiles = Directory.GetFiles(#"Path");
string[] FolderBFiles = Directory.GetFiles(#"BPath");
foreach (string Files in FolderAFiles)
{
if (FolderBFiles.Contains(Files))
{
File.Delete(Files);
}
}
Try this
Here's one another solution.
var filesInB = System.IO.Directory.GetFiles("FolderB");
Array.ForEach(System.IO.Directory.GetFiles("FolderA"), delegate(string fileName){
if (filesInB.Contains(fileName)) System.IO.File.Delete(fileName);
});
I have this code to list all the files in a directory.
class GetTypesProfiler
{
static List<Data> Test()
{
List<Data> dataList = new List<Data>();
string folder = #"DIRECTORY";
Console.Write("------------------------------------------\n");
var files = Directory.GetFiles(folder, "*.dll");
Stopwatch sw;
foreach (var file in files)
{
string fileName = Path.GetFileName(file);
var fileinfo = new FileInfo(file);
long fileSize = fileinfo.Length;
Console.WriteLine("{0}/{1}", fileName, fileSize);
}
return dataList;
}
static void Main()
{
...
}
}
I need to print out the file info based on file size or alphabetical order. How can I sort the result from Directory.GetFiles()?
Very easy with LINQ.
To sort by name,
var sorted = Directory.GetFiles(".").OrderBy(f => f);
To sort by size,
var sorted = Directory.GetFiles(".").OrderBy(f => new FileInfo(f).Length);
To order by date: (returns an enumerable of FileInfo):
Directory.GetFiles(folder, "*.dll").Select(fn => new FileInfo(fn)).
OrderBy(f => f.Length);
or, to order by name:
Directory.GetFiles(folder, "*.dll").Select(fn => new FileInfo(fn)).
OrderBy(f => f.Name);
Making FileInfo instances isn't necessary for ordering by file name, but if you want to apply different sorting methods on the fly it's better to have your array of FileInfo objects in place and then just OrderBy them by Length or Name property, hence this implementation. Also, it looks like you are going to create FileInfo anyway, so it's better to have a collection of FileInfo objects either case.
Sorry I didn't get it right the first time, should've read the question and the docs more carefully.
You can use LINQ if you like, on a FileInfo object:
var orderedFiles = Directory.GetFiles("").Select(f=> new FileInfo(f)).OrderBy(f=> f.CreationTime)
try this, it works for me
[System.Runtime.InteropServices.DllImport("Shlwapi.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode)]
private static extern int StrCmpLogicalW(string psz1, string psz2);
DirectoryInfo di = new DirectoryInfo(path);
FileInfo[] arrFi = di.GetFiles("*.*");
Array.Sort(arrFi, delegate(FileInfo x, FileInfo y) { return StrCmpLogicalW(x.Name, y.Name); });
This works if you only need to sort by file name and the file title supports the ascending or descending logical order.I add variables to have a bit more control of the source and search pattern.
Using Dir = System.IO;
string Source = yourVariable;
string SearchPattern = yourVariable;
Dir.Directory.GetFiles(Source, SearchPattern, Dir.SearchOption.AllDirectories).OrderBy(s => s).ToList();
// Getting Directory object
DirectoryInfo directoryInfo = new DirectoryInfo(folderName);
// getting files for this folder
FileInfo[] files = directoryInfo.GetFiles();
// Sorting using the generic Array.Sort function based on Names comparison
Array.Sort(files, delegate (FileInfo x, FileInfo y) { return String.Compare(x.Name, y.Name); });
// Sorting using the generic Array.Sort function based on the creation date of every folder
Array.Sort(files, delegate (FileInfo x, FileInfo y) { return DateTime.Compare(x.CreationTime, y.CreationTime); });
Array Sort
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
}