I have a OpenFileDialog and I want to convert selected file names to a FileInfo[] variable.
But I don't know how to convert all the selected files in one line code.
This obviously doesn't work:
FileInfo[] files = openFileDialog.FileNames;
Thank you.
Using LINQ:
FileInfo[] files = openFileDialog.FileNames.Select(f => new FileInfo(f)).ToArray();
The FileInfo class offers a constructor that expects a filename. Therefore, to get a FileInfo instance for a single filename string, simply call that constructor:
FileInfo file = new FileInfo(openFileDialog.FileName);
In your case, you want to get an array and have several filename strings, therefore you can use the LINQ extension methods from the Enumerable class:
FileInfo[] files = openFileDialog.FileNames.Select(fn => new FileInfo(fn)).ToArray();
Note the additional call to ToArray in the end, as Select will return an IEnumerable<FileInfo>.
Related
FileInfo[] comList = new FileInfo[]{};
FileInfo[] files
DirectoryInfo dInfo;
string[] folderList = path.Split(',');
foreach (string folder in folderList){
dInfo = new DirectoryInfo(folder);
files = dInfo.GetFiles().Where(F => extensions.Contains(f.Extension.ToLower())).ToArray();
comList.Concat(files);
}
I am trying to read multiple folders and get all the files into one FileInfo[], but after doing the concat to comList, my comList is still empty.
the path input is something like string path = "pathA,pathB,pathC"
if this is not the way to do it, what is a better ways to get all the files from different directory into one.
According to Microsoft documentation Concat will returns a new collection without modifying existing one:
public static System.Collections.Generic.IEnumerable<TSource> Concat<TSource> (
this System.Collections.Generic.IEnumerable<TSource> first,
System.Collections.Generic.IEnumerable<TSource> second);
Therefore in your scenario assigning the statement back to comList as following and you're good to go!
comList = comList.Concat(files);
Nonetheless, if you're not constraining yourself to use array for comList, you may consider to use List instead which allow us to achieve the same without redundant cast:
List<FileInfo> comList = new List<FileInfo>();
...
foreach (string folder in folderList) {
var dInfo = new DirectoryInfo(folder);
var files = dInfo.GetFiles().Where(f =>
extensions.Contains(
f.Extension.ToLower()));
comList.AddRange(files);
}
You need to use the return of comList.Concat(files), like:
comList = comList.Concat(files).ToArray();
The ToArray() method is needed because Concat() returns an IEnumerable.
Alternatively you can make comList an actual List<FileInfo> and use its AddRange method in each iteration:
comList.AddRange(files);
DirectoryInfo d = new DirectoryInfo(mypath);//Assuming Test is your Folder
FileInfo[] Files = d.GetFiles("*.jpg"); //Getting Text files
How the files array could be order by name?
let's say
files[0].Name is 'hi1.jpg'
files[1].Name is 'hi2.jpg'
and so on
It is just a call to OrderBy in Linq namespace
using System.Linq;
....
FileInfo[] Files = d.GetFiles("*.jpg").OrderBy(x => x.Name).ToArray();
By the way, I suggest you to use EnumerateFiles instead of GetFiles. In particular if you have to loop over the result like this
foreach(FileInfo fi in d.EnumerateFiles("*.jpg").OrderBy(x => x.Name))
Console.WriteLine(fi.Name);
As explained in the MSDN documentation
The EnumerateFiles and GetFiles methods differ as follows: When you
use EnumerateFiles, you can start enumerating the collection of
FileInfo objects before the whole collection is returned. When you
use GetFiles, you must wait for the whole array of FileInfo objects to
be returned before you can access the array.
FileInfo[] Files = d.GetFiles("*.jpg").OrderBy(f => f.Name).ToArray();
Using Linq
d.GetFiles("*.jpg").OrderBy(file=> file.Name).ToArray();
FileInfo[] files = d.GetFiles("*.jpg").OrderBy(file => file.Name).ToArray();
As answered above .ToArray() function along with OrderBy(columnName) does the job.
Based on the documentation on MSDN for DirectoryInfo.EnumerateFiles, the process involves:
declaring DirectoryInfo with the path
using the EnumerateFiles method to retrieve files
There are underlying classes that retrieve this information such as FileInfo dependent on FileSystemInfo.
DirectoryInfo DR = new DirectoryInfo(#"C:\temp\Downloads");
foreach(FileInfo FF in DR.EnumerateFiles())
{
textBox1.Text += FF.ToString()+ "\r\n";
}
How do I re-code this where I can declare FileInfo before using it
directly?
How would I re-code this if I were to use List<T>?
How would I read the list enumerable data?
Thanks
Why do you want to?
var list = DR.EnumerateFiles().ToList();
It's not all that clear what you are trying to do, but nonetheless, you can 'declare it before using it', by doing the below:
DirectoryInfo DR = new DirectoryInfo(#"C:\temp\Downloads");
List<string> filePaths = DR.EnumerateFiles();
IEnumerable<FileInfo> fileInfos = filePaths.Select(f => new FileInfo(f));
foreach(FileInfo fileInfo in fileInfos)
{
textBox1.Text += fileInfo.FullName.ToString()+ "\r\n";
}
(That is, just move the declaration outside the foreach loop)
Since EnumerateFiles returns the full path of the file, so you'd need to create FileInfo instances out of that, which you can do using the constructor provided for you.
To do the 'list' bit you've talked about, you just add ToList() and LINQ will do the work for you:
List<FileInfo> fileInfos = filePaths.Select(f => new FileInfo(f)).ToList();
I am trying to extract a list of files within a folder and am currently using:
string[] files = Directory.GetFiles(txtbxNewFolder.Text);
But that returns things like "C:\Users\Dahlia\Desktop\New Folder\jerry.txt". Is there a way to return only "jerry.txt", or do I need to do some sort of split on the array strings?
I am also trying to return a list of folders within a directory and am currently using:
string[] folders = Directory.GetDirectories(txtbxOldFolder.Text);
But that returns things like "C:\Users\Dahlia\Desktop\New Folder\folder1". Is there a way to return only "folder1", or do I need to do some sort of split on the array strings?
Using LINQ you can get a list of just the files:
Directory.GetFiles(txtbxNewFolder.Text).Select(f => Path.GetFileName(f));
Though rather than GetFiles I'd probably use:
Directory.EnumerateFiles(txtbxNewFolder.Text).Select(f => Path.GetFileName(f));
It isn't as simple to get the directory name, but this should work (untested):
Directory.GetDirectories(txtbxOldFolder.Text)
.Select(d => new DirectoryInfo(d).Name);
Similarly, there is a:
Directory.EnumerateDirectories(txtbxOldFolder.Text)
.Select(d => new DirectoryInfo(d).Name);
You could use Path.GetFileName and LINQ
e.g.:
string[] files = Directory.GetFiles(txtbxNewFolder.Text)
.Select(f => Path.GetFileName(s))
.ToArray();
Have a look at the FileInfo and DirectoryInfo classes.
You can do:
foreach (String file in files) {
var fi = new FileInfo(file);
Console.Out.WriteLine(fi.Name);
}
Similar for DirectoryInfo.
I used this code to get the contents of a directory:
string[] savefile = Directory.GetFiles(mcsdir, "*.bin");
comboBox1.Items.AddRange(savefile);
and it returns as
C:\Users\Henry\MCS\save1.bin
C:\Users\Henry\MCS\save2.bin
How can I make it return as only
save1.bin
save2.bin
Please note that this app will be used by other people, so the name is not always "Henry".
Thank you.
I would recommend using DirectoryInfo.GetFiles instead, and LINQ:
FileInfo[] savefile = new DirectoryInfo(mcsdir).GetFiles("*.bin");
comboBox1.Items.AddRange(savefile.Select(x => x.Name).ToArray());
Use LINQ:
var strs = savefile.Select(a => Path.GetFileName(a)).ToArray();
Looking at the suggestion of minitech:
As long as you get the array of type FileInfo[] there is no need to convert it to string array. Just set the property DisplayMember to the property name you want to display in your ComboBox.
FileInfo[] savefile = new DirectoryInfo(mcsdir).GetFiles("*.bin");
comboBox1.DisplayMember = "Name";
comboBox1.DataSource = savefile;
Using this you keep your original FileInfo[] array with all additional information (as to the full path to your files) and same time display only the short filenames (without path) in your control.
(I assume that your question is about WinForms. If you are using Silverlight or WPF you need to set the property using the "Target" attribute).
Use Path.GetFileName(string path).