So I am making a little test, and when using a listbox it says "C:/Test/Text.txt" but I want it to say Text.txt. So I currently have
private void FlatButton3_Click(object sender, EventArgs e)
{
ListBox1.Items.Clear();
string folder = #"C:/Aatrox";
string[] txtfiles = Directory.GetFiles(folder, "*.txt");
string[] luafiles = Directory.GetFiles(folder, "*.lua");
foreach (var item in folder)
{
ListBox1.Items.Add(Path.GetFileName(Convert.ToString(txtfiles)));
}
}
and in the ListBox it says System.String[]
Any help?
If you want both the .lua files and the .txt files (and you are using .NET 4.5 or later) you can use some LINQ to grab the files you want:
ListBox1.Items.Clear();
var files = Directory.EnumerateFiles(#"C:/Aatrox")
.Where(file => file.ToLower().EndsWith("lua")
|| file.ToLower().EndsWith("txt"));
foreach(var file in files)
{
ListBox1.Items.Add(Path.GetFileName(file));
}
It might actually be faster to use a non-LINQ approach like this:
ListBox1.Items.Clear();
foreach(var file in Directory.EnumerateFiles(#"C:/Aatrox"))
{
string extension = Path.GetExtension(file);
if(string.Compare(extension, ".lua", true) == 0
|| string.Compare(extension, ".txt", true) == 0)
{
ListBox1.Items.Add(Path.GetFileName(file));
}
}
Thanks to #maccettura I have got it.
private void FlatButton3_Click(object sender, EventArgs e)
{
ListBox1.Items.Clear();
string folder = #"C:/Aatrox";
string[] txtfiles = Directory.GetFiles(folder, "*.txt");
string[] luafiles = Directory.GetFiles(folder, "*.lua");
foreach (var item in txtfiles)
{
ListBox1.Items.Add(Path.GetFileName(item));
}
}
You are looping in folder variable and using txtfiles variable instead of item. Also, converting a String to String is useless. Maybe your code shall be like:
private void FlatButton3_Click(object sender, EventArgs e)
{
ListBox1.Items.Clear();
string folder = #"C:/Aatrox";
string[] txtfiles = Directory.GetFiles(folder, "*.txt");
string[] luafiles = Directory.GetFiles(folder, "*.lua");
foreach (var item in txtfiles)
{
ListBox1.Items.Add(Path.GetFileName(item));
}
}
Extra: if you also want to list *.lua files, you have to do another foreach loop.
This is far from the most efficient answer, but one that will hopefully help you understand.
var filenames = Directory.GetFiles("C:/Aatrox", "*.txt").ToList();
filenames.AddRange(Directory.GetFiles("C:/Aatrox", "*.lua"));
foreach (var filename in filenames)
listBox.Add(Path.GetFileName(filename));
var files = Directory.GetFiles(path, "*.*", SearchOption.Recursive);
var filter = files.Where(file => file.Contains(".txt") || file.Contains(".lua"));
foreach(var file in filter)
listbox.Items.Add(new FileInfo(file).Name);
Code is pretty simple, grab the files within directory, use Linq to filter out the extensions you want. Then loop through, convert to FileInfo to use the Name property that uses the short 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 have been using the following lines to search a folder structure for specific filetypes and just copy those filetypes and maintain their original folder structure. It works very well.
Is there any modification I can make to my method to only copy the directories that contain the filtered filetype?
*edit: I can let the user select a only certain set of files, (example *.dwg or *.pdf), using text box named txtFilter.
private void button1_Click(object sender, EventArgs e)
{
string sourceFolder = txtSource.Text;
string destinationFolder = txtDestination.Text;
CopyFolderContents(sourceFolder, destinationFolder);
}
// Copies the contents of a folder, including subfolders to an other folder, overwriting existing files
public void CopyFolderContents(string sourceFolder, string destinationFolder)
{
string filter = txtFilter.Text;
if (Directory.Exists(sourceFolder))
{
// Copy folder structure
foreach (string sourceSubFolder in Directory.GetDirectories(sourceFolder, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
}
// Copy files
foreach (string sourceFile in Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories))
{
string destinationFile = sourceFile.Replace(sourceFolder, destinationFolder);
File.Copy(sourceFile, destinationFile, true);
}
}
}
Something like this in your main loop?
if (Directory.EnumerateFiles(sourceSubFolder, "*.pdf").Any())
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
or for multiple file types:
if (Directory.EnumerateFiles(sourceSubFolder).Where(x => x.ToLower.EndsWith(".pdf") || x.ToLower.EndsWith(".dwg")).Any())
Directory.CreateDirectory(sourceSubFolder.Replace(sourceFolder, destinationFolder));
You can simply concatenate both operations into one loop and complete the algorithm in O(n).
foreach(string sourceFile in Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories))
{
Directory.CreateDirectory(Path.GetDirectoryName(sourceFile.Replace(sourceFolder,destinationFolder)));
File.Copy(sourceFile,sourceFile.Replace(sourceFolder,destinationFolder),true);
}
You can get the distinct directories from the files you find, then iterate through them and create the directories before copying the files.
if (Directory.Exists(sourceFolder))
{
var files = Directory.GetFiles(sourceFolder, filter, SearchOption.AllDirectories);
foreach(string directory in files.Select(f => Path.GetDirectoryName(f)).Distinct())
{
string destinationDirectory = directory.Replace(sourceFolder, destinationFolder);
if (!Directory.Exists(destinationDirectory))
{
Directory.CreateDirectory(destinationDirectory);
}
}
foreach (string sourceFile in files)
{
string destinationFile = sourceFile.Replace(sourceFolder, destinationFolder);
File.Copy(sourceFile, destinationFile, true);
}
}
I have an app that reads a CSV file called “words.csv”. My new requirement is that 1) it needs to ensure that there is only one CSV file in the directory before reading. 2) It should read any file with ".CSV" extension not just “words.csv” (after condition 1 is satisfied). Hope this makes sense?
Can anyone assist?
public class VM
{
public VM()
{
Words = LoadWords(fileList[0]);
}
public IEnumerable<string> Words { get; private set; }
string[] fileList = Directory.GetFiles(#"Z:\My Documents\", "*.csv");
private static IEnumerable<string> LoadWords(String fileList)
{
List<String> words = new List<String>();
if (fileList.Length == 1)
{
try
{
foreach (String line in File.ReadAllLines(fileList))
{
string[] rows = line.Split(',');
words.AddRange(rows);
}
}
catch (Exception e)
{
System.Windows.MessageBox.Show(e.Message);
}
return words;
}
}
}
You can use this code to get a list of all the csv files in a folder:
string[] fileList = Directory.GetFiles( #"Z:\My Documents\", "*.csv");
So to satisfy your conditions, this should do the trick:
string[] fileList = Directory.GetFiles( #"Z:\My Documents\", "*.csv");
if( fileList.Length == 1 )
{
//perform your logic here
}
DirectoryInfo di = new DirectoryInfo(#"Z:\My Documents");
// Get a reference to each file in that directory.
FileInfo[] fiArr = di.GetFiles();
if(fiArr.Length ==1)
{
FileInfo fri = fiArr[0];
//use fri.Extension to check for csv
//process as required
}
MSDN:DirectoryInfo.GetFiles
MSDN: FileInfo
FileInfo file = new DirectoryInfo(#"Z:\My Documents")
.EnumerateFiles("*.csv")
.SingleOrDefault();
if (file != null)
{
//do your logic
}
Linq's SingleOrDefault operator will make sure there's exactly onle file with the given pattern otherwise it will return null
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