This question is similar:
Possible to specify directory path with a wildcard?
However in my case I want to obtain all files from every single folder named 'data' that is a first child of all folders in my directory.
Hypothetically what I would need is the following:
string[] files = System.IO.Directory.GetFiles(directory + "\\Share\\*\\data");
*'directory' is simply a string of the directory path
Wildcards are not accepted in both GetFiles and GetDirectories methods and it is my understanding, they must be used as filters as a second parameter (both these methods have that overload). However in the GetFiles case, it is specifically to filter files and not directories, and in the GetDirectories case, it is giving me the same error, as if the filter was only applicable on the lowest level directories (or something of the sort).
I could do this with multiple calls to GetDirectories and GetFiles in
a loop, but I'd rather find a more
elegant solution. (i.e. What I want to avoid:: Get all directories
under my directory\Share, loop through and add get all files for each
\data directory of those, agglomerate all of that into a list of
strings for my file names etc...)
EDIT - SOLUTION:: Actually #Steve Wong pointed me towards the solution I went with (hopefully regexes aren't a big no-no):
Regex reg = new Regex(#"^\\" + directory + #"\\Share\\.*\\data\\.*\.xml$");
List<string> files = System.IO.Directory.GetFiles(connect + "\\Share","*.*",SearchOption.AllDirectories).Where(path => reg.IsMatch(path)).ToList();
Thanks for the help!
You could try this:
string rootDirectory = directory + "\\Share\\";
var files = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories).Where(
(directoryPath) => StringComparer.OrdinalIgnoreCase.Compare(Path.GetFileName(directoryPath), "Data") == 0).SelectMany(
(directoryPath) => Directory.GetFiles(directoryPath, "*"));
The Where clause will return all folder paths that end with a "Data/data" folder, and then the SelectMany returns all files in those folders.
Related
Currently I am looping through my file system like this
For Each filename As String In Directory.GetFiles(sourceFolder, "*.doc")
However this is including docx files to the list of files that GetFiles returns. I wish to only search for doc files and not docx. Any idea if there is a truncate or stop search character I can use in the search pattern?
This is the default behaviour of GetFiles, you can use LINQ to do further filtering.
var files = Directory.GetFiles(#"C:\test", "*.doc")
.Where(file=> file.EndsWith(".doc", StringComparison.CurrentCultureIgnoreCase))
.ToArray();//If you want an array back
Directory.GetFiles Method (String, String)
When you use the asterisk wildcard character in a searchPattern such
as "*.txt", the number of characters in the specified extension
affects the search as follows:
If the specified extension is exactly three characters long, the method returns files with extensions that begin with the specified extension. For example, "*.xls" returns both "book.xls" and "book.xlsx".
Given the fact that you want to iterate over your files and considering the default behavior of these methods I suggest to use EnumerateFiles instead of GetFiles. In this way you could add a simple check on the extension of the current file
foreach(string filename in Directory.EnumerateFiles(sourceFolder, "*.doc"))
{
if(!filename.EndsWith("x", StringComparison.CurrentCultureIgnoreCase))
{
.....
}
}
Not elegant as the Linq only solution but still working and not creating an array of all the filenames present in the directory
I am not a C# programmer so may be there can be syntax mistake, but i think it may solve your problem.
foreach (FileInfo fi in di.GetFiles("*.doc")
.Where(fi => string.Compare(".doc", fi.Extension,
StringComparison.OrdinalIgnoreCase) == 0))
{
myFiles.Add(fi);
}
I'm trying to get the files count from a remote directory using a SFTP connection, but I'm getting . and .. and these are counted these dots like a files, I have 2 files in the remote directory but is counting 4 files including . and ...
Someone can help me how to solve this?
This is my code:
filesCount = session.ListDirectory(DataFile.sRemoteDirectory).Files.Count;
Thanks!
According to the WinSCP documentation:
You can use Session.EnumerateRemoteFiles method instead, if you want to:
List only files matching a wildcard;
List the files recursively;
Have references to this (.) and parent (..) directories be excluded form the listing.
So it appears that you should change your code to do something more like this:
filesCount = 0;
filesCount = session.EnumerateRemoteFiles(DataFile.sRemoteDirectory).Files.Count();
session.Close();
Instead of using ListDirectory you can use EnumerateRemoteFiles and it wont include ".." and "."
"." and ".." mean this directory and parent directory respectively.
The . and .. are references to this and parent directories respectively on most file systems.
To filter them, you can use new properties .IsThisDirectory and .IsParentDirectory of the RemoteFileInfo class:
filesCount =
session.ListDirectory(DataFile.sRemoteDirectory).Files
.Where(file => !file.IsThisDirectory && !file.IsParentDirectory).Count();
Note that you have to use the Enumerable.Count() extension method, instead of the ICollection.Count property as the result of the Enumerable.Where() is the IEnumerable, not the Collection anymore.
Or to make it even easier, use the Session.EnumerateRemoteFiles() method, which with the EnumerationOptions.None option is functionally equivalent to the Session.ListDirectory(), just that it excludes the . and ...
filesCount =
session.EnumerateRemoteFiles(
DataFile.sRemoteDirectory, null, EnumerationOptions.None).Count();
If you want to filter all directories, use:
filesCount =
session.ListDirectory(DataFile.sRemoteDirectory).Files
.Where(file => !file.IsDirectory).Count();
Try session.EnumerateRemoteFiles instead.
Despite its naming, Files collection contains not only files, but all directory entries, including current and parent directory references.
If you want to count only files, filter them by IsDirectory property:
var filesCount = session.ListDirectory(dir).Files.Where(x => !x.IsDirectory).Count();
There's also IsParentDirectory and IsThisDirectory properties in the latest versions to filter ".." and "." cases without name comparison.
I have a fairly unique situation. Did a lot of searching and most of what I'm seeing terminates at finding a particular file, using wildcards ("*.txt") as an example. What I need to do is move a file between paths, the first one having a changing subdirectory. I am downloading a .zip, extracting it, and moving a file who's name never changes. Its parent directory does change in name, based on a datestamp.
//original extracted folder
string path = #"C:\IP-Test_20140715\File.csv";
//where to move
string path2 = #"C:\File.csv";
File.csv will never change, yet IP-Test_20140715 will change based on the date (whatever the extracted folder is called), everything after the underscore will be different going forward.
If not possible to have wildcards in directories, is it possible to force the name of the extracted directory in c# using ZipFile.ExtractToDirectory?
Use:
Directory.EnumerateFiles (#"C:\IP-Test_20140715", "*.txt")
to enumerate over the different files.
Thus:
foreach(var subdir in Directory.EnumerateDirectories (#"C:\", "IP-Test_*")) {
foreach(var file in Directory.EnumerateFiles (subdir, "*.cvs")) {
File.Move(file,Path.Combine(#"C:\",Path.GetFileName(file)));
}
}
On the other hand, I don't see why you want to use C# for this? A simple bash script could do the trick way easier...
I want to write a search algoritham for searching files having extension .txt(the occurance of all .txt file) in another group of files.ie i have a directory named d:\myfolder.I have a files of extension .txt in this folderin as well as subfolders.
There are also files of extension .proj,.dat,.cs etc in this folder as well as subfolders.I want to search the occurance of .txt files in these files
I thought to create a list(LISTA) that contain the names of all .txt files and also create a seperate list(ListB) containg the fullpath of all other files.Then iterate throgh the
lists to get the result.Is that a better method.Else is there any other better method
If you want to search for a particular file in folder and sub folder then easiest would be to use Directory.GetFiles like
string path = #"C:\YourFolder";
string[] txtFiles = System.IO.Directory.GetFiles(path,
"*.txt",
SearchOption.AllDirectories);
You don't have to populate two different lists, one with txt extensions and one without. Directory.GetFiles would let you find all the txt files in a folder and sub folder.
if you use LINQ:
List<FileInfo> list = new List<FileInfo>();
list= list.Where(a => a.Extension == Path.GetExtension(a.FullName)).ToList();
I was wondering how I could use c# to find a specific file (example cheese.exe) within all possible directories? And then store the path to the directory it found it in?
This code fragment retrieves a list of all logical drives on the machine and then searches all folders on the drive for files that match the filename "Cheese.exe". Once the loop has completed, the List "files" contains the
var files = new List<string>();
//#Stan R. suggested an improvement to handle floppy drives...
//foreach (DriveInfo d in DriveInfo.GetDrives())
foreach (DriveInfo d in DriveInfo.GetDrives().Where(x => x.IsReady == true))
{
files.AddRange(Directory.GetFiles(d.RootDirectory.FullName, "Cheese.exe", SearchOption.AllDirectories));
}
If you want to know a little more about the mechanics of searching multiple directories, Googling revealed this post. It has a good solution and explanation of recursing through directories yourself. You can change the filespec in Directory.GetFiles to match your search string and probably use it as is.
The link is unfortunately dead now, but in a nutshell the solution basically boils down to:
string[] files = Directory.GetFiles("C:\\Starting\\Path\\For\\Search\\",
"cheese.exe",
SearchOption.AllDirectories);
Note the filespec (second parameter) accepts wildcards, so you can also search for ".exe" or even ".*" to list all files recursively.