I create a FileInfo array like this
try
{
DirectoryInfo Dir = new DirectoryInfo(DirPath);
FileInfo[] FileList = Dir.GetFiles("*.*", SearchOption.AllDirectories);
foreach (FileInfo FI in FileList)
{
Console.WriteLine(FI.FullName);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
And this array holds all the file names in folder = DirPath
I thought of looping through the FileInfo array and copy it to a String array. Is this ok or is there a much cleaner method ?
Using LINQ:
FileList.Select(f => f.FullName).ToArray();
Alternatively, using Directory you can get filenames directly.
string[] fileList = Directory.GetFiles(DirPath, "*.*",
SearchOption.AllDirectories);
If you want to go the other way (convert string array into FileInfo's) you can use the following:
string[] files;
var fileInfos = files.Select(f => new FileInfo(f));
List<FileInfo> infos = fileInfos.ToList<FileInfo>();
the linq is a great soluction, but for the persons who don't want to use linq, i made this function:
static string BlastWriteFile(FileInfo file)
{
string blasfile = " ";
using (StreamReader sr = file.OpenText())
{
string s = " ";
while ((s = sr.ReadLine()) != null)
{
blasfile = blasfile + s + "\n";
Console.WriteLine();
}
}
return blasfile;
}
Try this one
DirectoryInfo directory = new DirectoryInfo("your path");
List<string> Files = (directory.GetFiles().Where(file => file.LastWriteTime >= date_value)).Select(f => f.Name).ToList();
If you don't want a filter with date, you can simply convert with the below code
List<string> logFiles = directory.GetFiles().Select(f => f.Name).ToList();
If you need the full path of the file, you can use FullName instead of Name.
Related
I'm trying to match a file name to a partial string in a List. The list will have something like 192 in it and the matching file will be xxx192.dat. Using .Contains does not match the file name to the string in the List. Can anyone tell me how to get this done or how to use wildcard chars in the contains?
Code below.
// use this to get a specific list of files
private List<string> getFiles(string path, List<string> filenames)
{
List<string> temp = new List<string>();
string mapPath = Server.MapPath(path);
//DirectoryInfo Di = new DirectoryInfo(mapPath);
DirectoryInfo Di = new DirectoryInfo(#"C:\inetpub\wwwroot\Distribution\" + path); // for testing locally
FileInfo[] Fi = Di.GetFiles();
foreach (FileInfo f in Fi)
{
if (filenames.Contains(f.Name)) **// *** this never matches**
temp.Add(f.FullName);
}
return temp;
}
I'v changed the code trying to use the suggestions but it's still not working. I'll add in the data like I'm stepping through the code.
// use this to get a specific list of files
private List<string> getFiles(string path, List<string> filenames)
{
List<string> temp = new List<string>();
string mapPath = Server.MapPath(path);
//DirectoryInfo Di = new DirectoryInfo(mapPath);
DirectoryInfo Di = new DirectoryInfo(#"C:\inetpub\wwwroot\Distribution\" + path); // for testing locally
foreach (string s in filenames) // list has 228,91,151,184 in it
{
FileInfo[] Fi = Di.GetFiles(s); // s = 228: Fi = {System.IO.FileInfo[0]}
foreach (FileInfo f in Fi) //Fi = {System.IO.FileInfo[0]}
{
temp.Add(f.FullName);
}
}
return temp;
}
When I look at the directory where these files are I can see:
pbset228.dat
pbmrc228.dat
pbput228.dat
pbext228.dat
pbget228.dat
pbmsg228.dat
This is working now. It may not be the most efficient way to do this, but it gets the job done. Maybe someone can post a sample that does the same thing in a better way.
// use this to get a specific list of files
private List<string> getFiles(string path, List<string> filenames)
{
List<string> temp = new List<string>();
string mapPath = Server.MapPath(path);
//DirectoryInfo Di = new DirectoryInfo(mapPath);
DirectoryInfo Di = new DirectoryInfo(#"C:\inetpub\wwwroot\Distribution\" + path); // for testing locally
FileInfo[] Fi = Di.GetFiles();
foreach (FileInfo f in Fi)
{
foreach (string s in filenames)
{
if (f.Name.Contains(s))
temp.Add(f.FullName);
}
}
return temp;
}
You can use the Any() LINQ extension:
filenames.Any(s => s.EndsWith(f.Name));
This will return True if any element in the enumeration returns true for the given function.
For anything more complex, you could use a regular expression to match:
filenames.Any(s => Regex.IsMatch(s, "pattern"));
Use the static Directory.GetFiles method that lets you include a wildcards and will be more efficient that retrieving all the files and then having to iterate through them.
Or you can even use DirectoryInfo.GetFiles and pass your search string to that.
Change this
foreach (FileInfo f in Fi)
{
if (filenames.Contains(f.Name)) **// *** this never matches**
temp.Add(f.FullName);
}
return temp;
Into something like this
temp = filenames.Find(file => file.Contains(someNameYoureLookingFor));
Is there any way to exclude certain directories from SearchOption using LINQ command like this
string path = "C:\SomeFolder";
var s1 = Directory.GetFiles(path , "*.*", SearchOption.AllDirectories);
var s2 = Directory.GetDirectories(path , "*.*", SearchOption.AllDirectories);
The path consists of Sub1 and Sub2 Folders with certain files in it. I need to exclude them from directory search.
Thanks
This Worked:
string[] exceptions = new string[] { "c:\\SomeFolder\\sub1",
"c:\\SomeFolder\\sub2" };
var s1 = Directory.GetFiles("c:\\x86", "*.*",
SearchOption.AllDirectories).Where(d => exceptions.All(e =>
!d.StartsWith(e)));
This helped with Exceptions
No there isn't as far as I know. But you could use very simple LINQ to do that in a single line.
var s1 = Directory.GetFiles(path , "*.*", SearchOption.AllDirectories).Where(d => !d.StartsWith("<EXCLUDE_DIR_PATH>")).ToArray();
You can easily combine multiple exclude DIRs too.
You can't do exactly what you want with simple LINQ methods. You will need to write a recursive routine instead of using SearchOption.AllDirectories. The reason is that you want to filter directories not files.
You could use the following static method to achieve what you want:
public static IEnumerable<string> GetFiles(
string rootDirectory,
Func<string, bool> directoryFilter,
string filePattern)
{
foreach (string matchedFile in Directory.GetFiles(rootDirectory, filePattern, SearchOption.TopDirectoryOnly))
{
yield return matchedFile;
}
var matchedDirectories = Directory.GetDirectories(rootDirectory, "*.*", SearchOption.TopDirectoryOnly)
.Where(directoryFilter);
foreach (var dir in matchedDirectories)
{
foreach (var file in GetFiles(dir, directoryFilter, filePattern))
{
yield return file;
}
}
}
You would use it like this:
var files = GetFiles("C:\\SearchDirectory", d => !d.Contains("AvoidMe", StringComparison.OrdinalIgnoreCase), "*.*");
Why the added complexity? This method completely avoids looking inside directories you're not interested in. The SearchOption.AllDirectories will, as the name suggests, search within all directories.
If you're not familiar with iterator methods (the yield return syntax), this can be written differently: just ask!
Alternative
This has almost the same effect. However, it still finds files within subdirectories of the directories you want to ignore. Maybe that's OK for you; the code is easier to follow.
public static IEnumerable<string> GetFilesLinq(
string root,
Func<string, bool> directoryFilter,
string filePattern)
{
var directories = Directory.GetDirectories(root, "*.*", SearchOption.AllDirectories)
.Where(directoryFilter);
List<string> results = new List<string>();
foreach (var d in directories)
{
results.AddRange(Directory.GetFiles(d, filePattern, SearchOption.TopDirectoryOnly));
}
return results;
}
try this
var s2 = Directory.GetDirectories(dirPath, "*", SearchOption.AllDirectories)
.Where(directory => !directory.Contains("DirectoryName"));
///used To Load Files And Folder information Present In Dir In dir
private void button1_Click(object sender, EventArgs e)
{
FileInfo[] fileInfoArr;
StringBuilder sbr=new StringBuilder();
StringBuilder sbrfname = new StringBuilder();
string strpathName = #"C:\Users\prasad\Desktop\Dll";
DirectoryInfo dir = new DirectoryInfo(strpathName);
fileInfoArr = dir.GetFiles("*.dll");
//Load Files From RootFolder
foreach (FileInfo f in fileInfoArr)
{
sbrfname.AppendLine(f.FullName);
}
DirectoryInfo[] dirInfos = dir.GetDirectories("*.*");
//Load Files from folder folder
foreach (DirectoryInfo d in dirInfos)
{
fileInfoArr = d.GetFiles("*.dll");
foreach (FileInfo f in fileInfoArr)
{
sbrfname.AppendLine(f.FullName);
}
sbr.AppendLine(d.ToString());
}
richTextBox1.Text = sbr.ToString();
richTextBox2.Text = sbrfname.ToString();
}
I need to take all file in particular directory and store them in fileinfo array and sort them alphanumerically.
code snippet
string dir = #"C:\tem";
DirectoryInfo directory = new DirectoryInfo(dir);
if (directory != null)
{
FileInfo[] files = directory.GetFiles("*.bmp");
if (files.Length > 0)
{
Console.WriteLine("Files:");
foreach (FileInfo subFile in files)
{
Console.WriteLine(" " + subFile.Name + " (" + subFile.Length + " bytes)");
}
}
}`
currently i am getting output
test_1.bmp test_11.bmp test_2.bmp
but i want the output like
test_1.bmp,test_2.bmp,test_11.bmp
Thanks
You can use LINQ for that:
if (directory != null)
{
FileInfo[] files = directory.GetFiles("*.bmp");
files.Select(f => f.Name).ToList().
OrderBy(x=> Int32.Parse(x.Substring(x.IndexOf('_') + 1, x.IndexOf('.') - x.IndexOf('_') - 1))).
ToList().ForEach(s => Console.WriteLine(s));
}
The output is:
test_1.bmp
test_2.bmp
test_11.bmp
UPDATE:
// Store as FileInfo array
FileInfo[] sortedFiles = files.OrderBy(x => Int32.Parse(x.Name.Substring(x.Name.IndexOf('_') + 1, x.Name.IndexOf('.') - x.Name.IndexOf('_') - 1))).
ToArray();
// Do whatever you want
foreach (FileInfo item in sortedFiles)
{
Console.WriteLine(string.Format("FullPath -> {0}", item.FullName));
}
public static void Main()
{
string dir = #"C:\tem";
var directory = new DirectoryInfo(dir);
FileInfo[] files = directory.GetFiles("*.bmp");
var sortedFiles=files.ToDictionary(k=>GetIntValueFromString(k.Name),v=>v).OrderBy(entry=>entry.Key);
foreach (var file in sortedFiles)
{
Console.WriteLine(file.Value.Name);
}
Console.Read();
}
static int GetIntValueFromString(string input)
{
var result = 0;
var intString = Regex.Replace(input, "[^0-9]+", string.Empty);
Int32.TryParse(intString, out result);
return result;
}
Use this code for search files in directory:
FileInfo[] files = null;
string path = some_path;
DirectoryInfo folder = new DirectoryInfo(path);
files = folder.GetFiles("*.*", SearchOption.AllDirectories);
This return only filename and extension (text.exe). How to return full path to file(C:\bla\bla\bla\text.exe)?
If I use Directory.GetFiles("*.*"), this return full path. But if folder contains point in name(C:\bla\bla\test.0.1), result contains path to folder without file:
0 C:\bla\bla\bla\text.exe
1 C:\bla\bla\test.0.1
2 C:\bla\text.exe
etc.
FileInfo contains a FullName property, which you can use to retrieve full path to a file
var fullNames = files.Select(file => file.FullName).ToArray();
Check
This code on my machine:
FileInfo[] files = null;
string path = #"C:\temp";
DirectoryInfo folder = new DirectoryInfo(path);
files = folder.GetFiles("*.*", SearchOption.AllDirectories);
//you need string from FileInfo to denote full path
IEnumerable<string> fullNames = files.Select(file => file.FullName);
Console.WriteLine ( string.Join(Environment.NewLine, fullNames ) );
prints
C:\temp\1.dot
C:\temp\1.jpg
C:\temp\1.png
C:\temp\1.txt
C:\temp\2.png
C:\temp\a.xml
...
Full solution
The solution to your problem might look like this:
string path = #"C:\temp";
DirectoryInfo folder = new DirectoryInfo(path);
var directories = folder.GetDirectories("*.*", SearchOption.AllDirectories);
IEnumerable<string> directoriesWithDot =
directories.Where(dir => dir.Name.Contains("."))
.Select(dir => dir.FullName);
IEnumerable<string> filesInDirectoriesWithoutDot =
directories.Where(dir => !dir.Name.Contains("."))
.SelectMany(dir => dir.GetFiles("*.*", SearchOption.TopDirectoryOnly))
.Select(file => file.FullName);
Console.WriteLine ( string.Join(Environment.NewLine, directoriesWithDot.Union(filesInDirectoriesWithoutDot) ) );
Each FileInfo object has a FullName property.
But if folder contains point in name (C:\bla\bla\test.0.1), result contains path to folder without file
This is an entirely different issue with possibly diffeent answers/workarounds. Can you be more specific?
I cannot reproduce this.
You need to use FileInfo.
Directory.GetFiles("", SearchOption.AllDirectories).Select(file => new FileInfo(file).FullName);
public static IEnumerable<string> GetAllFilesRecursively(string inputFolder)
{
var queue = new Queue<string>();
queue.Enqueue(inputFolder);
while (queue.Count > 0)
{
inputFolder = queue.Dequeue();
try
{
foreach (string subDir in Directory.GetDirectories(inputFolder))
{
queue.Enqueue(subDir);
}
}
catch (Exception ex)
{
Console.Error.WriteLine("GetAllFilesRecursively: " + ex);
}
string[] files = null;
try
{
files = Directory.GetFiles(inputFolder);
}
catch (Exception ex)
{
Console.Error.WriteLine("GetAllFilesRecursively: " + ex);
}
if (files != null)
{
for (int i = 0; i < files.Length; i++)
{
yield return files[i];
}
}
}
}
you can try this :
void GetFiles()
{
DirectoryInfo d= new DirectoryInfo(strFolderPath);
//file extension for pdf
var files = d.GetFiles("*.pdf*");
FileInfo[] subfileInfo = files.ToArray<FileInfo>();
if (subfileInfo.Length > 0)
{
for (int j = 0; j < subfileInfo.Length; j++)
{
bool isHidden = ((File.GetAttributes(subfileInfo[j].FullName) & FileAttributes.Hidden) == FileAttributes.Hidden);
if (!isHidden)
{
string strExtention = th.GetExtension(subfileInfo[j].FullName);
if (strExtention.Contains("pdf"))
{
string path = subfileInfo[j].FullName;
string name = bfileInfo[j].Name;
}
}
}
}
You can use FileSystemInfo.FullName property.
Gets the full path of the directory or file.
I am trying to get all images from folder but ,this folder also include sub folders. like /photos/person1/ and /photos/person2/ .I can get photos in folder like
path= System.IO.Directory.GetCurrentDirectory() + "/photo/" + groupNO + "/";
public List<String> GetImagesPath(String folderName)
{
DirectoryInfo Folder;
FileInfo[] Images;
Folder = new DirectoryInfo(folderName);
Images = Folder.GetFiles();
List<String> imagesList = new List<String>();
for (int i = 0; i < Images.Length; i++)
{
imagesList.Add(String.Format(#"{0}/{1}", folderName, Images[i].Name));
// Console.WriteLine(String.Format(#"{0}/{1}", folderName, Images[i].Name));
}
return imagesList;
}
But how can I get all photos in all sub folders? I mean I want to get all photos in /photo/ directory at once.
Have a look at the DirectoryInfo.GetFiles overload that takes a SearchOption argument and pass SearchOption.AllDirectories to get the files including all sub-directories.
Another option is to use Directory.GetFiles which has an overload that takes a SearchOption argument as well:
return Directory.GetFiles(folderName, "*.*", SearchOption.AllDirectories)
.ToList();
I'm using GetFiles wrapped in method like below:
public static String[] GetFilesFrom(String searchFolder, String[] filters, bool isRecursive)
{
List<String> filesFound = new List<String>();
var searchOption = isRecursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
foreach (var filter in filters)
{
filesFound.AddRange(Directory.GetFiles(searchFolder, String.Format("*.{0}", filter), searchOption));
}
return filesFound.ToArray();
}
It's easy to use:
String searchFolder = #"C:\MyFolderWithImages";
var filters = new String[] { "jpg", "jpeg", "png", "gif", "tiff", "bmp", "svg" };
var files = GetFilesFrom(searchFolder, filters, false);
There's a good one-liner solution for this on a similar thread:
get all files recursively then filter file extensions with LINQ
Or if LINQ cannot be used, then use a RegEx to filter file extensions:
var files = Directory.GetFiles("C:\\path", "*.*", SearchOption.AllDirectories);
List<string> imageFiles = new List<string>();
foreach (string filename in files)
{
if (Regex.IsMatch(filename, #"\.jpg$|\.png$|\.gif$"))
imageFiles.Add(filename);
}
I found the solution this Might work
foreach (string img in Directory.GetFiles(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"*.bmp" + "*.jpg" + "SO ON"))
You need the recursive form of GetFiles:
DirectoryInfo.GetFiles(pattern, searchOption);
(specify AllDirectories as the SearchOption)
Here's a link for more information:
MSDN: DirectoryInfo.GetFiles
This allows you to use use the same syntax and functionality as Directory.GetFiles(path, pattern, options); except with an array of patterns instead of just one.
So you can also use it to do tasks like find all files that contain the word "taxes" that you may have used to keep records over the past year (xlsx, xls, odf, csv, tsv, doc, docx, pdf, txt...).
public static class CustomDirectoryTools {
public static string[] GetFiles(string path, string[] patterns = null, SearchOption options = SearchOption.TopDirectoryOnly) {
if(patterns == null || patterns.Length == 0)
return Directory.GetFiles(path, "*", options);
if(patterns.Length == 1)
return Directory.GetFiles(path, patterns[0], options);
return patterns.SelectMany(pattern => Directory.GetFiles(path, pattern, options)).Distinct().ToArray();
}
}
In order to get all image files on your c drive you would implement it like this.
string path = #"C:\";
string[] patterns = new[] {"*.jpg", "*.jpeg", "*.jpe", "*.jif", "*.jfif", "*.jfi", "*.webp", "*.gif", "*.png", "*.apng", "*.bmp", "*.dib", "*.tiff", "*.tif", "*.svg", "*.svgz", "*.ico", "*.xbm"};
string[] images = CustomDirectoryTools.GetFiles(path, patterns, SearchOption.AllDirectories);
You can use GetFiles
GetFiles("*.jpg", SearchOption.AllDirectories)
GetFiles("*.jpg", SearchOption.AllDirectories) has a problem at windows7. If you set the directory to c:\users\user\documents\, then it has an exception: because of windows xp, win7 has links like Music and Pictures in the Documents folder, but theese folders don't really exists, so it creates an exception. Better to use a recursive way with try..catch.
This will get list of all images from folder and sub folders and it also take care for long file name exception in windows.
// To handle long folder names Pri external library is used.
// Source https://github.com/peteraritchie/LongPath
using Directory = Pri.LongPath.Directory;
using DirectoryInfo = Pri.LongPath.DirectoryInfo;
using File = Pri.LongPath.File;
using FileInfo = Pri.LongPath.FileInfo;
using Path = Pri.LongPath.Path;
// Directory and sub directory search function
public void DirectoryTree(DirectoryInfo dr, string searchname)
{
FileInfo[] files = null;
var allFiles = new List<FileInfo>();
try
{
files = dr.GetFiles(searchname);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
if (files != null)
{
try
{
foreach (FileInfo fi in files)
{
allFiles.Add(fi);
string fileName = fi.DirectoryName + "\\" + fi.Name;
string orgFile = fileName;
}
var subDirs = dr.GetDirectories();
foreach (DirectoryInfo di in subDirs)
{
DirectoryTree(di, searchname);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
public List<String> GetImagesPath(String folderName)
{
var dr = new DirectoryInfo(folderName);
string ImagesExtensions = "jpg,jpeg,jpe,jfif,png,gif,bmp,dib,tif,tiff";
string[] imageValues = ImagesExtensions.Split(',');
List<String> imagesList = new List<String>();
foreach (var type in imageValues)
{
if (!string.IsNullOrEmpty(type.Trim()))
{
DirectoryTree(dr, "*." + type.Trim());
// output to list
imagesList.Add = DirectoryTree(dr, "*." + type.Trim());
}
}
return imagesList;
}
var files = new DirectoryInfo(path).GetFiles("File")
.OrderByDescending(f => f.LastWriteTime).First();
This could gives you the perfect result of searching file with its latest mod