Creating a getter for specific Directory visual C# - c#

I'm relatively new to Visual C# and I have been searching for a bit now. I cant find an actual solution to my problem (perhaps because i'm searching for the wrong way or thing).
So I want to create a getter that gives me the directory so I can convert the path name to a string.
This is the code I am using
(I already know that getDirectories gives an array of strings)
public Directory getDBDirectory() {
Directory db;
if (!Directory.Exists(itemFolder)) {
Console.WriteLine("Couldn't find directory.. is it created?");
} else {
db = Directory.GetDirectories(itemFolder);
}
return db;
}

To get the path for subdirectories:
string[] db = Directory.GetDirectories(itemFolder);
If you want to get Directory Info:
DirectoryInfo dir = new DirectoryInfo(somepath);
which you can access its name nad path by dir.Name and dir.FullName

Directory is a Static Class. I assumes you need to get all folders inside itemFolder.
So just change the return type to string[] instead, like this:
public string[] getDBDirectory() {
//Directory db; //no need
if (!Directory.Exists(itemFolder)) {
Console.WriteLine("Couldn't find directory.. is it created?");
return null;
} else {
return Directory.GetDirectories(itemFolder);
}
}
or if you just want to check if it exist:
public string getDBDirectory() {
if (!Directory.Exists(itemFolder)) {
Console.WriteLine("Couldn't find directory.. is it created?");
return null;
} else {
return itemFolder;
}
}
or if I understand you right, you can use Directory.CreateDirectory(itemFolder); that will Create If Not Exists.

Related

How can i get all files on disk with a specific extension using 'Directory.getFiles' and save them in a list

I'm doing a console project whose goal is to search the entire disk for all files with the extension '.config'
I've tried something like:
foreach (string file in Directory.GetFiles("C:\\", "*.config", SearchOption.AllDirectories))
{
Console.WriteLine(file);
Console.ReadLine();
}
but gave me an error "denied access to path (...)".
On the internet I found this code:
Stack<string> pending = new Stack<string>();
pending.Push("C:\\");
while (pending.Count != 0)
{
var path = pending.Pop();
string[] next = null;
try
{
next = Directory.GetFiles(path, "*.config");
}
catch { }
if (next != null && next.Length != 0)
foreach (var file in next)
{
Console.WriteLine(file);
Console.ReadLine();
}
try
{
next = Directory.GetDirectories(path);
foreach (var subdir in next) pending.Push(subdir);
}
catch { }
}
but it just shows the path clicking always in 'enter' and I want to save those files/path in a list.
Someone can help?
There are two things you can do to improve that code:
Use Directory.EnumerateFiles() and Directory.EnumerateDirectories() to avoid making a copy of the names of all the files in each directory.
Make the return type of the method IEnumerable<string> to make it easier to consume.
We also need to be very careful about exceptions caused by attempting to access protected files and directories. The code below is also complicated by the fact that you're not allowed to yield return from inside a try/catch block, so we have to rearrange the code somewhat.
(Also note that we have to dispose the enumerator returned from .GetEnumerator(); normally this is done automatically when you use foreach, but in this case we can't - because of having to avoid doing yield return in a try/catch - so we have to use using to dispose it.)
Here's a modification of your original code to do this:
public static IEnumerable<string> GetFiles(string root, string spec)
{
var pending = new Stack<string>(new []{root});
while (pending.Count > 0)
{
var path = pending.Pop();
IEnumerator<string> fileIterator = null;
try
{
fileIterator = Directory.EnumerateFiles(path, spec).GetEnumerator();
}
catch {}
if (fileIterator != null)
{
using (fileIterator)
{
while (true)
{
try
{
if (!fileIterator.MoveNext()) // Throws if file is not accessible.
break;
}
catch { break; }
yield return fileIterator.Current;
}
}
}
IEnumerator<string> dirIterator = null;
try
{
dirIterator = Directory.EnumerateDirectories(path).GetEnumerator();
}
catch {}
if (dirIterator != null)
{
using (dirIterator)
{
while (true)
{
try
{
if (!dirIterator.MoveNext()) // Throws if directory is not accessible.
break;
}
catch { break; }
pending.Push(dirIterator.Current);
}
}
}
}
}
As an example, here's how you could use a console app to list all the accessible ".txt" files on the "C:\" drive:
static void Main()
{
foreach (var file in GetFiles("C:\\", "*.txt"))
{
Console.WriteLine(file);
}
}
Replace the lines
Console.WriteLine(file);
Console.ReadLine();
with a method to store them in a list.
For example
foundFiles.Add(file);
Then when the method is done, you can read all found file paths from this list.
Notes:
This will not yield all files on the system that match the filter.
Only files where your application has access to their respective directory are found this way.
For example the Windows directory and user directories of other users are usually protected. (assuming you run on Windows)
Keep in mind, that some files might be protected independently of their directory.
So when trying to read them, also consider the fact, that the read might fail.
Just encompass the read with a try catch.
Regarding the error "denied access to path (...)", sometimes you have to run Visual Studio as an a administrator in order to access some folders in the C:\ drive.

C# Recursive folder search does not work properly

I need help, because I've written a method that should find a special directory on a computer that definitely exists.
First I've written a method that will be go through every drive on a computer and open up for every drive the recursive method.
private string LocateOnDrives()
{
string result = string.Empty;
string[] drives = Directory.GetLogicalDrives();
foreach (string drive in drives)
{
string buffer = this.Locate(drive);
if (buffer.EndsWith(SEARCH_PATTERN))
{
return buffer;
}
}
return result;
}
And this is the method that is called for every drive:
private string Locate(string directory)
{
string result = string.Empty;
try
{
string[] dirs = Directory.GetDirectories(directory);
foreach (string dir in dirs)
{
if (dir.EndsWith(SEARCH_PATTERN))
{
return dir;
}
else
{
result = this.Locate(dir);
}
}
}
catch { }
return result;
}
The try catch is necessary, because there are some directories with no permission. I have the permission for the sought folder and when i debug this, it will jump into the if condition that it has found and set the local 'result' to this sought folder. Up to this point it really makes that what was my intention. But the recursive method will search further and the overall return is string.Empty!
I already did something link this:
private string tragetDir;
private string Locate(string directory)
{
string result = string.Empty;
try
{
string[] dirs = Directory.GetDirectories(directory);
foreach (string dir in dirs)
{
if (dir.EndsWith(DEFAULT_GTAV_DIRECTORY_NAME))
{
targetDir = dir;
}
else
{
result = this.Locate(dir);
}
}
}
catch { }
return result;
This is working for me, but not what I wanted to have, because it should be possible that the recursive method will return this wanted folder…
It is late for me and I just want to fix this little mistake!
Can someone help me out, because I am desperate, THANKS!
When you find a match and return it, then unwind once in your nested calls to Locate(), you assign the match to result but then keep progressing with the loop, when you actually want to break out of it.
result = this.Locate(dir, SEARCH_PATTERN);
if (result.EndsWith(SEARCH_PATTERN))
{
break;
}
Also, you might consider just catching the UnauthorizedAccessException since that's the one it'll throw if you don't have permission to a particular directory.
This is a solution I tried and it worked for me now:
private string Locate(string directory)
{
string result = string.Empty;
string[] dirs = new string[0];
try
{
dirs = Directory.GetDirectories(directory);
}
catch { /* Ignore */ }
foreach (string dir in dirs)
{
if (dir.EndsWith(SEARCH_PATTERN))
{
result = dir;
break;
}
else
{
result = this.Locate(dir);
if (result.EndsWith(SEARCH_PATTERN))
{
break;
}
}
}
return result;
}
First I had to check if the current "dir" in the loop was already the sought folder. If not, the loop had to browse inside this folder and if the result inside this folder isn't the sought folder the loop had to going on and search on or in the next folder in loop.
In any case that the right directory was found, the loop will "break" and return the result!
This is it!

Opening files in another computer c#

I have a program that a button, when clicked, executes a sound located in my download folder. My question is how to execute the sound on another computer if the path for finding it is different.
You need the path to a file to run it. If you don't have the path - you have to search for it.
Pick a base directory where you think the file is. If you don't know where - that will be the whole drive.
Write a recursive function that would search said folder recursively.
Test each file by what ever your search condition is, i.e. file name, file hash, etc.
For example:
string SearchForFile(string searchPath, Func<string, bool> searchPredicate)
{
try
{
foreach (string fileName in Directory.EnumerateFiles(searchPath))
{
if (searchPredicate(fileName))
{
return fileName;
}
}
foreach (string dirName in Directory.EnumerateDirectories(searchPath))
{
var childResult = SearchForFile(dirName, searchPredicate);
if (childResult != null)
{
return childResult;
}
}
return null;
}
catch (UnauthorizedAccessException)
{
return null;
}
}
Usage:
var filePath = SearchForFile(#"C:\", x => Path.GetFileName(x) == "yourFileName.mp3");

string.IsNullOrEmpty to combine another directory

I want ask to find directory name it (folder1) to combine.
But if directory not exist, i want to find another directory name it (folder2) to combine.
What should i put to it?
Here the code:
public static string DataDirectory
{
get
{
if (string.IsNullOrEmpty(Directory))
return null;
return Path.Combine(Directory, "Data/folder1");
}
}
Thanks.
Directory.Exists should work fine
public static string DataDirectory
{
get
{
if (string.IsNullOrEmpty(Directory))
return null;
// Use Path.Combine just one time
string firstFolder = Path.Combine(Directory, "Data/folder1");
if(Directory.Exists(firstFolder)
return Path.Combine(firstFolder);
else
return Path.Combine(Directory, "Data/folder2");
}
}
you could also do something like this to first check if there are any directories, then use linq to order the directories and select the first element.
public static string GetDataDirectory(string root)
{
var directoryList = Directory.GetDirectories(root);
if (!directoryList.Any())
return null;
directoryList = directoryList.OrderBy(dir => dir).ToArray();
return directoryList.First();
}

How do I create a file AND any folders, if the folders don't exist?

Imagine I wish to create (or overwrite) the following file :- C:\Temp\Bar\Foo\Test.txt
Using the File.Create(..) method, this can do it.
BUT, if I don't have either one of the following folders (from that example path, above)
Temp
Bar
Foo
then I get an DirectoryNotFoundException thrown.
So .. given a path, how can we recursively create all the folders necessary to create the file .. for that path? If Temp or Bar folders exists, but Foo doesn't... then that is created also.
For simplicity, lets assume there's no Security concerns -- all permissions are fine, etc.
To summarize what has been commented in other answers:
//path = #"C:\Temp\Bar\Foo\Test.txt";
Directory.CreateDirectory(Path.GetDirectoryName(path));
Directory.CreateDirectory will create the directories recursively and if the directory already exist it will return without an error.
If there happened to be a file Foo at C:\Temp\Bar\Foo an exception will be thrown.
DirectoryInfo di = Directory.CreateDirectory(path);
Console.WriteLine("The directory was created successfully at {0}.",
Directory.GetCreationTime(path));
See this MSDN page.
Use Directory.CreateDirectory before you create the file. It creates the folder recursively for you.
. given a path, how can we recursively create all the folders necessary to create the file .. for that path
Creates all directories and subdirectories as specified by path.
Directory.CreateDirectory(path);
then you may create a file.
You will need to check both parts of the path (directory and filename) and create each if it does not exist.
Use File.Exists and Directory.Exists to find out whether they exist. Directory.CreateDirectory will create the whole path for you, so you only ever need to call that once if the directory does not exist, then simply create the file.
You should use Directory.CreateDirectory.
http://msdn.microsoft.com/en-us/library/54a0at6s.aspx
Assuming that your assembly/exe has FileIO permission is itself, well is not right. Your application may not run with admin rights. Its important to consider Code Access Security and requesting permissions
Sample code:
FileIOPermission f2 = new FileIOPermission(FileIOPermissionAccess.Read, "C:\\test_r");
f2.AddPathList(FileIOPermissionAccess.Write | FileIOPermissionAccess.Read, "C:\\example\\out.txt");
try
{
f2.Demand();
}
catch (SecurityException s)
{
Console.WriteLine(s.Message);
}
Understanding .NET Code Access Security
Is “Code Access Security” of any real world use?
You want Directory.CreateDirectory()
Here is a class I use (converted to C#) that if you pass it a source directory and a destination it will copy all of the files and sub-folders of that directory to your destination:
using System.IO;
public class copyTemplateFiles
{
public static bool Copy(string Source, string destination)
{
try {
string[] Files = null;
if (destination[destination.Length - 1] != Path.DirectorySeparatorChar) {
destination += Path.DirectorySeparatorChar;
}
if (!Directory.Exists(destination)) {
Directory.CreateDirectory(destination);
}
Files = Directory.GetFileSystemEntries(Source);
foreach (string Element in Files) {
// Sub directories
if (Directory.Exists(Element)) {
copyDirectory(Element, destination + Path.GetFileName(Element));
} else {
// Files in directory
File.Copy(Element, destination + Path.GetFileName(Element), true);
}
}
} catch (Exception ex) {
return false;
}
return true;
}
private static void copyDirectory(string Source, string destination)
{
string[] Files = null;
if (destination[destination.Length - 1] != Path.DirectorySeparatorChar) {
destination += Path.DirectorySeparatorChar;
}
if (!Directory.Exists(destination)) {
Directory.CreateDirectory(destination);
}
Files = Directory.GetFileSystemEntries(Source);
foreach (string Element in Files) {
// Sub directories
if (Directory.Exists(Element)) {
copyDirectory(Element, destination + Path.GetFileName(Element));
} else {
// Files in directory
File.Copy(Element, destination + Path.GetFileName(Element), true);
}
}
}
}
Following code will create directories (if not exists) & then copy files.
// using System.IO;
// for ex. if you want to copy files from D:\A\ to D:\B\
foreach (var f in Directory.GetFiles(#"D:\A\", "*.*", SearchOption.AllDirectories))
{
var fi = new FileInfo(f);
var di = new DirectoryInfo(fi.DirectoryName);
// you can filter files here
if (fi.Name.Contains("FILTER")
{
if (!Directory.Exists(di.FullName.Replace("A", "B"))
{
Directory.CreateDirectory(di.FullName.Replace("A", "B"));
File.Copy(fi.FullName, fi.FullName.Replace("A", "B"));
}
}
}

Categories