How can I browse a local virtual folder in C#? - c#

In my C# program I have to browse directories.
So I use the method
System.IO.Directory.GetFiles(directory) and it works well when directory is a real directory like "C:\Program File" but when it's a virtual directory (eg: librairie directory), directory value looks like this : "::{031E4825-7B94-4dc3-B131-E946B44C8DD5}\Pictures.library-ms" and I don't know how to browse it.

I know this is crazy old, but in case someone wants the solution, here is what I have figured out over the past half-day looking into this. There are several solutions out there that can get you the folder names if you give it the path to the Virtual Folder's XML location , but nothing I have seen gets you there from ::{031E4825-....}. There was a hint in another question's answer to use the WindowsAPICodePack's KnownFoldersBrowser example. So I read through the source code in that and have come up with the following:
Here is the DialogBox I was using to get folders, and I have enabled it for AllowNonFileSystemItems, which allows Library folder selections:
Microsoft.WindowsAPICodePack.Dialogs.CommonOpenFileDialog dlg = new Microsoft.WindowsAPICodePack.Dialogs.CommonOpenFileDialog();
dlg.Title = "Pick Folder";
dlg.IsFolderPicker = true;
dlg.InitialDirectory = Environment.SpecialFolder.Personal.ToString(); // If default setting does not exist, pick the Personal folder
dlg.AddToMostRecentlyUsedList = false;
dlg.AllowNonFileSystemItems = true;
dlg.DefaultDirectory = dlg.InitialDirectory;
dlg.EnsurePathExists = true;
dlg.EnsureFileExists = false;
dlg.EnsureReadOnly = false;
dlg.EnsureValidNames = true;
dlg.Multiselect = true;
dlg.ShowPlacesList = true;
if (dlg.ShowDialog() == Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialogResult.Ok)
{
foreach ( string dirname in dlg.FileNames )
{
var libFolders = ExpandFolderPath(dirname);
if ( libFolders == null )
{
MessageBox.Show("Could not add '" + dirname + "', please try another.");
}
else
{
foreach ( string libfolder in libFolders )
{
DoWork(libfolder);
}
}
}
}
I then iterate over allSpecialFolders to find this same ::{031E4825-...} which is the ParsingName for the SpecialFolder (yeah, probably a more elegant way). After that, use the XML reading from other solutions (I used a CodeProject example that did the same thing) to get the folders in that library folder:
/// <summary>Gets the folders associated with a path</summary>
/// <param name="libname"></param>
/// <returns>Folder, or List of folders in library, and null if there was an issue</string></returns>
public List<string> ExpandFolderPath(string foldername)
{
List<string> dirList = new List<string> { };
// If the foldername is an existing directory, just return that
if ( System.IO.Directory.Exists(foldername) )
{
dirList.Add(foldername);
return dirList;
}
// It's not a directory, so check if it's a GUID Library folder
ICollection<IKnownFolder> allSpecialFolders = Microsoft.WindowsAPICodePack.Shell.KnownFolders.All;
Regex libguid = new Regex(#"\b([A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12})\b");
var match = libguid.Match(foldername);
if ( match == null )
return null;
string fpath = "";
// Iterate over each folder and find the one we want
foreach ( var folder in allSpecialFolders )
{
if ( folder.ParsingName == foldername )
{
// We now have access to the xml path
fpath = folder.Path;
break;
}
}
if ( fpath == "" )
{
// Could not find it exactly, so find one with the same prefix, and
// replace the filename
foreach ( var folder in allSpecialFolders )
{
if ( folder.ParsingName.Contains(match.Groups[1].Value) )
{
string sameDir = System.IO.Path.GetDirectoryName(folder.Path);
string newPath = System.IO.Path.Combine(sameDir, match.Groups[2].Value);
if ( System.IO.File.Exists(newPath) )
fpath = newPath;
break;
}
}
}
if ( fpath == "" )
return null;
var intFolders = GetLibraryInternalFolders(fpath);
return intFolders.Folders.ToList();
}
/// <summary>
/// Represents an instance of a Windows 7 Library
/// </summary>
public class Win7Library
{
public Win7Library()
{
}
public string Name { get; set; }
public string[] Folders { get; set; }
}
[DllImport("shell32.dll")]
static extern int SHGetKnownFolderPath( [MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath );
//Handles call to SHGetKnownFolderPath
public static string getpathKnown( Guid rfid )
{
IntPtr pPath;
if ( SHGetKnownFolderPath(rfid, 0, IntPtr.Zero, out pPath) == 0 )
{
string s = System.Runtime.InteropServices.Marshal.PtrToStringUni(pPath);
System.Runtime.InteropServices.Marshal.FreeCoTaskMem(pPath);
return s;
}
else return string.Empty;
}
private static string ResolveStandardKnownFolders( string knowID )
{
if ( knowID.StartsWith("knownfolder:") )
{
return getpathKnown(new Guid(knowID.Substring(12)));
}
else
{
return knowID;
}
}
private static Win7Library GetLibraryInternalFolders( string libraryXmlPath )
{
Win7Library newLibrary = new Win7Library();
//The Name of a Library is just its file name without the extension
newLibrary.Name = System.IO.Path.GetFileNameWithoutExtension(libraryXmlPath);
List<string> folderpaths = new List<string>();
System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); //* create an xml document object.
xmlDoc.Load(libraryXmlPath); //* load the library as an xml doc.
//Grab all the URL tags in the document,
//these point toward the folders contained in the library.
System.Xml.XmlNodeList directories = xmlDoc.GetElementsByTagName("url");
foreach ( System.Xml.XmlNode x in directories )
{
//Special folders use windows7 Know folders GUIDs instead
//of full file paths, so we have to resolve them
folderpaths.Add(ResolveStandardKnownFolders(x.InnerText));
}
newLibrary.Folders = folderpaths.ToArray();
return newLibrary;
}
Hope this helps someone in future!

You need to translate the virtual path into a physical one, try:
DirectoryInfo directoryInfo = new DirectoryInfo(Server.MapPath("your virtual folder here"));
You might want to read up on DirectoryInfo. If that's no use, give this a try this instead:
DirectoryInfo info = new DirectoryInfo("virtual folder here");
FileInfo[] files = info.GetFiles("*.*", SearchOption.AllDirectories);

Related

How to get the list of files with specific extension in Xamarin Android?

I need suggestion on getting a list of PDF files from the external storage in android device
1.You could traverse the folder and filter the PDF files:
public void Search_Pdf_Dir(File dir)
{
string pdfPattern = ".pdf";
File[] FileList = dir.ListFiles();
if (FileList != null)
{
for (int i = 0; i < FileList.Length; i++)
{
if (FileList[i].IsDirectory)
{
Search_Pdf_Dir(FileList[i]);
}
else
{
if (FileList[i].Name.EndsWith(pdfPattern))
{
//here you have that file.
}
}
}
}
}
then you could call like Search_Pdf_Dir(Android.OS.Environment.ExternalStorageDirectory);
2.use MediaStore - Uri to query all types of files :
ContentResolver cr = ContentResolver;
Android.Net.Uri uri = MediaStore.Files.GetContentUri("external");
// every column, although that is huge waste, you probably need
// BaseColumns.DATA (the path) only.
string[] projection = null;
string selectionMimeType = MediaStore.Files.FileColumns.MediaType + "=?";
string mimeType = MimeTypeMap.Singleton.GetMimeTypeFromExtension("pdf");
string[] selectionArgsPdf = new string[] { mimeType };
string sortOrder = null;
var allPdfFiles = cr.Query(uri, projection, selectionMimeType, selectionArgsPdf, sortOrder);
while (allPdfFiles.MoveToNext())
{
int column_index = allPdfFiles.GetColumnIndexOrThrow(MediaStore.Images.Media.InterfaceConsts.Data);
string filePath = allPdfFiles.GetString(column_index);//the pdf path
}

Is it possible to create a generic method for extracting text out of a file?

I'm creating a spyware program that craws the entire file system of a computer and looks for any text that it can find and sends it to my accompanying web service. The problem I'm having is, once I have a file, it is either a type of file from which I can extract text (i.e. if it's a .txt., .docx, .xml, etc. file) or it's not. If it is, I want to extract the text from it. What I have right now is
private string _accumulatedInfo;
public FileCrawler ( )
{
this._accumulatedInfo = String.Empty;
}
private void GrabInfo ( System.IO.FileInfo fi )
{
// if can parse text out of file, add text to accumulated info string
// ...
}
private void _WalkDirectoryTree ( System.IO.DirectoryInfo root )
{
System.IO.FileInfo[] files = root.GetFiles("*.*");
if ( files != null )
{
foreach ( System.IO.FileInfo fi in files )
{
GrabInfo(fi);
}
}
System.IO.DirectoryInfo[] subDirs = root.GetDirectories();
if ( subDirs != null )
{
foreach ( System.IO.DirectoryInfo dirInfo in subDirs )
{
this._WalkDirectoryTree(dirInfo);
}
}
}
private void CrawlAllDrives ( )
{
string[] drives = System.Environment.GetLogicalDrives();
foreach ( string dr in drives )
{
System.IO.DriveInfo di = new System.IO.DriveInfo(dr);
if ( di.IsReady )
{
System.IO.DirectoryInfo rootDir = di.RootDirectory;
this._WalkDirectoryTree(rootDir);
}
}
}
and I'm wondering how to, or whether it's even possible to, implement my
private void GrabInfo ( System.IO.FileInfo fi )
{
// if can parse text out of file, add text to accumulated info string
// ...
}
method without resorting to something like
private void GrabInfo ( System.IO.FileInfo fi )
{
switch (fi.Extension)
{
case "txt":
// ...
case "docx":
// ...
// ...
}
}
Does there exist some generic way of extracting text from a file?
You can do something like the following:
System.IO.DirectoryInfo path = new DirectoryInfo( #"c:\temp");
System.IO.FileInfo[] files = path.GetFiles("*.*");
if ( files != null )
{
foreach ( System.IO.FileInfo fi in files.Where(f => MimeMapping.GetMimeMapping(f.FullName).StartsWith("text/")))
{
try
{
var text = File.ReadAllText(fi.FullName);
}
catch
{
// something bad happened
}
}
}
This will give you back all the types that are "text" like.
You can read more about it in this answer.

Renci SSH.NET: Is it possible to create a folder containing a subfolder that does not exist

I am currently using Renci SSH.NET to upload files and folders to a Unix Server using SFTP, and creating directories using
sftp.CreateDirectory("//server/test/test2");
works perfectly, as long as the folder "test" already exists. If it doesn't, the CreateDirectory method fails, and this happens everytime when you try to create directories containing multiple levels.
Is there an elegant way to recursively generate all the directories in a string? I was assuming that the CreateDirectory method does that automatically.
There's no other way.
Just iterate directory levels, testing each level using SftpClient.GetAttributes and create the levels that do not exist.
static public void CreateDirectoryRecursively(this SftpClient client, string path)
{
string current = "";
if (path[0] == '/')
{
path = path.Substring(1);
}
while (!string.IsNullOrEmpty(path))
{
int p = path.IndexOf('/');
current += '/';
if (p >= 0)
{
current += path.Substring(0, p);
path = path.Substring(p + 1);
}
else
{
current += path;
path = "";
}
try
{
SftpFileAttributes attrs = client.GetAttributes(current);
if (!attrs.IsDirectory)
{
throw new Exception("not directory");
}
}
catch (SftpPathNotFoundException)
{
client.CreateDirectory(current);
}
}
}
A little improvement on the code provided by Martin Prikryl
Don't use Exceptions as a flow control mechanism. The better alternative here is to check if the current path exists first.
if (client.Exists(current))
{
SftpFileAttributes attrs = client.GetAttributes(current);
if (!attrs.IsDirectory)
{
throw new Exception("not directory");
}
}
else
{
client.CreateDirectory(current);
}
instead of the try catch construct
try
{
SftpFileAttributes attrs = client.GetAttributes(current);
if (!attrs.IsDirectory)
{
throw new Exception("not directory");
}
}
catch (SftpPathNotFoundException)
{
client.CreateDirectory(current);
}
Hi I found my answer quite straight forwared. Since I found this old post, I thought others might also stumble upon it. The accepted answer is not that good, so here is my take. It does not use any counting gimmicks, so I think it's a little more easy to understand.
public void CreateAllDirectories(SftpClient client, string path)
{
// Consistent forward slashes
path = path.Replace(#"\", "/");
foreach (string dir in path.Split('/'))
{
// Ignoring leading/ending/multiple slashes
if (!string.IsNullOrWhiteSpace(dir))
{
if(!client.Exists(dir))
{
client.CreateDirectory(dir);
}
client.ChangeDirectory(dir);
}
}
// Going back to default directory
client.ChangeDirectory("/");
}
FWIW, here's my rather simple take on it. The one requirement is that the server destination path is seperated by forward-slashes, as is the norm. I check for this before calling the function.
private void CreateServerDirectoryIfItDoesntExist(string serverDestinationPath, SftpClient sftpClient)
{
if (serverDestinationPath[0] == '/')
serverDestinationPath = serverDestinationPath.Substring(1);
string[] directories = serverDestinationPath.Split('/');
for (int i = 0; i < directories.Length; i++)
{
string dirName = string.Join("/", directories, 0, i + 1);
if (!sftpClient.Exists(dirName))
sftpClient.CreateDirectory(dirName);
}
}
HTH
A little modification on the accepted answer to use spans.
It's probably utterly pointless in this case, since the overhead of the sftp client is far greater than copying strings, but it can be useful in other similiar scenarios:
public static void EnsureDirectory(this SftpClient client, string path)
{
if (path.Length is 0)
return;
var curIndex = 0;
var todo = path.AsSpan();
if (todo[0] == '/' || todo[0] == '\\')
{
todo = todo.Slice(1);
curIndex++;
}
while (todo.Length > 0)
{
var endOfNextIndex = todo.IndexOf('/');
if (endOfNextIndex < 0)
endOfNextIndex = todo.IndexOf('\\');
string current;
if (endOfNextIndex >= 0)
{
curIndex += endOfNextIndex + 1;
current = path.Substring(0, curIndex);
todo = path.AsSpan().Slice(curIndex);
}
else
{
current = path;
todo = ReadOnlySpan<char>.Empty;
}
try
{
client.CreateDirectory(current);
}
catch (SshException ex) when (ex.Message == "Already exists.") { }
}
}
my approach is more sufficient and easier to read and maintain
public static void CreateDirectoryRecursively(this ISftpClient sftpClient, string path)
{
// Consistent forward slashes
var separators = new char[] { Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar };
string[] directories = path.Split(separators);
string currentDirectory = "";
for (int i = 1; i < directories.Length; i++)
{
currentDirectory = string.Join("/", currentDirectory, directories[i]);
if (!sftpClient.Exists(currentDirectory))
{
sftpClient.CreateDirectory(currentDirectory);
}
}
}

C#: split file path [duplicate]

My path is \\server\folderName1\another name\something\another folder\
How do I extract each folder name into a string if I don't know how many folders there are in the path and I don't know the folder names?
Many thanks
string mypath = #"..\folder1\folder2\folder2";
string[] directories = mypath.Split(Path.DirectorySeparatorChar);
Edit:
This returns each individual folder in the directories array. You can get the number of folders returned like this:
int folderCount = directories.Length;
This is good in the general case:
yourPath.Split(#"\/", StringSplitOptions.RemoveEmptyEntries)
There is no empty element in the returned array if the path itself ends in a (back)slash (e.g. "\foo\bar\"). However, you will have to be sure that yourPath is really a directory and not a file. You can find out what it is and compensate if it is a file like this:
if(Directory.Exists(yourPath)) {
var entries = yourPath.Split(#"\/", StringSplitOptions.RemoveEmptyEntries);
}
else if(File.Exists(yourPath)) {
var entries = Path.GetDirectoryName(yourPath).Split(
#"\/", StringSplitOptions.RemoveEmptyEntries);
}
else {
// error handling
}
I believe this covers all bases without being too pedantic. It will return a string[] that you can iterate over with foreach to get each directory in turn.
If you want to use constants instead of the #"\/" magic string, you need to use
var separators = new char[] {
Path.DirectorySeparatorChar,
Path.AltDirectorySeparatorChar
};
and then use separators instead of #"\/" in the code above. Personally, I find this too verbose and would most likely not do it.
I see your method Wolf5370 and raise you.
internal static List<DirectoryInfo> Split(this DirectoryInfo path)
{
if(path == null) throw new ArgumentNullException("path");
var ret = new List<DirectoryInfo>();
if (path.Parent != null) ret.AddRange(Split(path.Parent));
ret.Add(path);
return ret;
}
On the path c:\folder1\folder2\folder3 this returns
c:\
c:\folder1
c:\folder1\folder2
c:\folder1\folder2\folder3
In that order
OR
internal static List<string> Split(this DirectoryInfo path)
{
if(path == null) throw new ArgumentNullException("path");
var ret = new List<string>();
if (path.Parent != null) ret.AddRange(Split(path.Parent));
ret.Add(path.Name);
return ret;
}
will return
c:\
folder1
folder2
folder3
Realise this is an old post, but I came across it looking - in the end I decided apon the below function as it sorted what I was doing at the time better than any of the above:
private static List<DirectoryInfo> SplitDirectory(DirectoryInfo parent)
{
if (parent == null) return null;
var rtn = new List<DirectoryInfo>();
var di = parent;
while (di.Name != di.Root.Name)
{
rtn.Add(di);
di = di.Parent;
}
rtn.Add(di.Root);
rtn.Reverse();
return rtn;
}
There are a few ways that a file path can be represented. You should use the System.IO.Path class to get the separators for the OS, since it can vary between UNIX and Windows. Also, most (or all if I'm not mistaken) .NET libraries accept either a '\' or a '/' as a path separator, regardless of OS. For this reason, I'd use the Path class to split your paths. Try something like the following:
string originalPath = "\\server\\folderName1\\another\ name\\something\\another folder\\";
string[] filesArray = originalPath.Split(Path.AltDirectorySeparatorChar,
Path.DirectorySeparatorChar);
This should work regardless of the number of folders or the names.
public static IEnumerable<string> Split(this DirectoryInfo path)
{
if (path == null)
throw new ArgumentNullException("path");
if (path.Parent != null)
foreach(var d in Split(path.Parent))
yield return d;
yield return path.Name;
}
Inspired by the earlier answers, but simpler, and without recursion. Also, it does not care what the separation symbol is, as Dir.Parent covers this:
/// <summary>
/// Split a directory in its components.
/// Input e.g: a/b/c/d.
/// Output: d, c, b, a.
/// </summary>
/// <param name="Dir"></param>
/// <returns></returns>
public static IEnumerable<string> DirectorySplit(this DirectoryInfo Dir)
{
while (Dir != null)
{
yield return Dir.Name;
Dir = Dir.Parent;
}
}
Either stick this in a static class to create a nice extension method, or just leave out the this (and static).
Usage example (as an extension method) to access the path parts by number:
/// <summary>
/// Return one part of the directory path.
/// Path e.g.: a/b/c/d. PartNr=0 is a, Nr 2 = c.
/// </summary>
/// <param name="Dir"></param>
/// <param name="PartNr"></param>
/// <returns></returns>
public static string DirectoryPart(this DirectoryInfo Dir, int PartNr)
{
string[] Parts = Dir.DirectorySplit().ToArray();
int L = Parts.Length;
return PartNr >= 0 && PartNr < L ? Parts[L - 1 - PartNr] : "";
}
Both above methods are now in my personal library, hence the xml comments. Usage example:
DirectoryInfo DI_Data = new DirectoryInfo(#"D:\Hunter\Data\2019\w38\abc\000.d");
label_Year.Text = DI_Data.DirectoryPart(3); // --> 2019
label_Entry.Text = DI_Data.DirectoryPart(6);// --> 000.d
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/// <summary>
/// Use to emulate the C lib function _splitpath()
/// </summary>
/// <param name="path">The path to split</param>
/// <param name="rootpath">optional root if a relative path</param>
/// <returns>the folders in the path.
/// Item 0 is drive letter with ':'
/// If path is UNC path then item 0 is "\\"
/// </returns>
/// <example>
/// string p1 = #"c:\p1\p2\p3\p4";
/// string[] ap1 = p1.SplitPath();
/// // ap1 = {"c:", "p1", "p2", "p3", "p4"}
/// string p2 = #"\\server\p2\p3\p4";
/// string[] ap2 = p2.SplitPath();
/// // ap2 = {#"\\", "server", "p2", "p3", "p4"}
/// string p3 = #"..\p3\p4";
/// string root3 = #"c:\p1\p2\";
/// string[] ap3 = p1.SplitPath(root3);
/// // ap3 = {"c:", "p1", "p3", "p4"}
/// </example>
public static string[] SplitPath(this string path, string rootpath = "")
{
string drive;
string[] astr;
path = Path.GetFullPath(Path.Combine(rootpath, path));
if (path[1] == ':')
{
drive = path.Substring(0, 2);
string newpath = path.Substring(2);
astr = newpath.Split(new[] { Path.DirectorySeparatorChar }
, StringSplitOptions.RemoveEmptyEntries);
}
else
{
drive = #"\\";
astr = path.Split(new[] { Path.DirectorySeparatorChar }
, StringSplitOptions.RemoveEmptyEntries);
}
string[] splitPath = new string[astr.Length + 1];
splitPath[0] = drive;
astr.CopyTo(splitPath, 1);
return splitPath;
}
Maybe call Directory.GetParent in a loop? That's if you want the full path to each directory and not just the directory names.
The quick answer is to use the .Split('\\') method.
I use this for looping folder ftp server
public List<string> CreateMultiDirectory(string remoteFile)
var separators = new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar };
string[] directory = Path.GetDirectoryName(remoteFile).Split(separators);
var path = new List<string>();
var folder = string.Empty;
foreach (var item in directory)
{
folder += $#"{item}\";
path.Add(folder);
}
return path;
Or, if you need to do something with each folder, have a look at the System.IO.DirectoryInfo class. It also has a Parent property that allows you to navigate to the parent directory.
I wrote the following method which works for me.
protected bool isDirectoryFound(string path, string pattern)
{
bool success = false;
DirectoryInfo directories = new DirectoryInfo(#path);
DirectoryInfo[] folderList = directories.GetDirectories();
Regex rx = new Regex(pattern);
foreach (DirectoryInfo di in folderList)
{
if (rx.IsMatch(di.Name))
{
success = true;
break;
}
}
return success;
}
The lines most pertinent to your question being:
DirectoryInfo directories = new DirectoryInfo(#path);
DirectoryInfo[] folderList = directories.GetDirectories();
DirectoryInfo objDir = new DirectoryInfo(direcotryPath);
DirectoryInfo [] directoryNames = objDir.GetDirectories("*.*", SearchOption.AllDirectories);
This will give you all the directories and subdirectories.
I am adding to Matt Brunell's answer.
string[] directories = myStringWithLotsOfFolders.Split(Path.DirectorySeparatorChar);
string previousEntry = string.Empty;
if (null != directories)
{
foreach (string direc in directories)
{
string newEntry = previousEntry + Path.DirectorySeparatorChar + direc;
if (!string.IsNullOrEmpty(newEntry))
{
if (!newEntry.Equals(Convert.ToString(Path.DirectorySeparatorChar), StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine(newEntry);
previousEntry = newEntry;
}
}
}
}
This should give you:
"\server"
"\server\folderName1"
"\server\folderName1\another name"
"\server\folderName1\another name\something"
"\server\folderName1\another name\something\another folder\"
(or sort your resulting collection by the string.Length of each value.
Here's a modification of Wolf's answer that leaves out the root and fixes what seemed to be a couple of bugs. I used it to generate a breadcrumbs and I didn't want the root showing.
this is an extension of the DirectoryInfo type.
public static List<DirectoryInfo> PathParts(this DirectoryInfo source, string rootPath)
{
if (source == null) return null;
DirectoryInfo root = new DirectoryInfo(rootPath);
var pathParts = new List<DirectoryInfo>();
var di = source;
while (di != null && di.FullName != root.FullName)
{
pathParts.Add(di);
di = di.Parent;
}
pathParts.Reverse();
return pathParts;
}
I just coded this since I didn't find any already built in in C#.
/// <summary>
/// get the directory path segments.
/// </summary>
/// <param name="directoryPath">the directory path.</param>
/// <returns>a IEnumerable<string> containing the get directory path segments.</returns>
public IEnumerable<string> GetDirectoryPathSegments(string directoryPath)
{
if (string.IsNullOrEmpty(directoryPath))
{ throw new Exception($"Invalid Directory: {directoryPath ?? "null"}"); }
var currentNode = new System.IO.DirectoryInfo(directoryPath);
var targetRootNode = currentNode.Root;
if (targetRootNode == null) return new string[] { currentNode.Name };
var directorySegments = new List<string>();
while (string.Compare(targetRootNode.FullName, currentNode.FullName, StringComparison.InvariantCultureIgnoreCase) != 0)
{
directorySegments.Insert(0, currentNode.Name);
currentNode = currentNode.Parent;
}
directorySegments.Insert(0, currentNode.Name);
return directorySegments;
}
I'd like to contribute using this options (without split method)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace SampleConsoleApp
{
class Program
{
static void Main(string[] args)
{
var filePaths = new[]
{
"C:/a/b/c/d/files-samples/formdata.bmp",
#"\\127.0.0.1\c$\a\b\c\d\formdata.bmp",
"/usr/home/john/a/b/c/d/formdata.bmp"
};
foreach (var filePath in filePaths)
{
var directorySegments = GetDirectorySegments(filePath);
Console.WriteLine(filePath);
Console.WriteLine(string.Join(Environment.NewLine,
directorySegments.Select((e, i) => $"\t Segment#={i + 1} Text={e}")));
}
}
private static IList<string> GetDirectorySegments(string filePath)
{
var directorySegments = new List<string>();
if (string.IsNullOrEmpty(filePath))
return directorySegments;
var fileInfo = new FileInfo(filePath);
if (fileInfo.Directory == null)
return directorySegments;
for (var currentDirectory = fileInfo.Directory;
currentDirectory != null;
currentDirectory = currentDirectory.Parent)
directorySegments.Insert(0, currentDirectory.Name);
return directorySegments;
}
}
}
if everything goes well, an output will be like:
C:/a/b/c/d/files-samples/formdata.bmp
Segment#=1 Text=C:\
Segment#=2 Text=a
Segment#=3 Text=b
Segment#=4 Text=c
Segment#=5 Text=d
Segment#=6 Text=files-samples
\\127.0.0.1\c$\a\b\c\d\formdata.bmp
Segment#=1 Text=\\127.0.0.1\c$
Segment#=2 Text=a
Segment#=3 Text=b
Segment#=4 Text=c
Segment#=5 Text=d
/usr/home/john/a/b/c/d/formdata.bmp
Segment#=1 Text=C:\
Segment#=2 Text=usr
Segment#=3 Text=home
Segment#=4 Text=john
Segment#=5 Text=a
Segment#=6 Text=b
Segment#=7 Text=c
Segment#=8 Text=d
You can still perform additional filters to GetDirectorySegments (since you have an instance of DirectoryInfo you can check atributes or use the Exist property)

C# how to check if file is in folder according to object of filenames

I have the following method:
public static Boolean CheckContents(string ExportDirectory, string FileName, string DspFleName, String RteFleName, string FulRteName, string EqpFleName, int CompanyId, string CompanyName)
{
if (DspFleName != "None")
{
IList<string> DspFle= DspFleName.Split(',');
IList<string> ActualFiles = Directory.GetFiles(ExportDirectory);
for (int i = 0; i < DspFle.Count; i++)
{
if (DspFle[i] != ActualFiles[i])
{
return false;
}
}
}
return true;
}
}
Basically what this code is meant to do is get all file names from the DspFle field which is seperated by a ,. So this would look like so:
test.txt,test2.csv
Then it is getting the acutal files in the directory that is specified from 'ExportDirectory' and returns those into an IList
I am having 2 problems here:
1.The Directory.GetFiles returns the whole file path so that will always return false. I also tried Path.GetFileNames and this only returns the file name but it does not return the extension.
2.I need to compare my entire DspFle to my ActualFile IList as the file names could be in different parts of the list.
Any ideas?
Your code expects not only for the file to exist, but to be in the same position...
Try this one instead :
public static Boolean CheckContents(string ExportDirectory, string DspFleName)
{
if (DspFleName == "None")
return true;
var DspFle = DspFleName.Split(',');
var ActualFiles = Directory.GetFiles(ExportDirectory);
foreach(var file in DspFle)
if (!ActualFiles.Any(x=>Path.GetFileName(x).Equals(file)))
return false;
return true;
}
List<String> fileNames = new List<String>();
String[] files = Directory.GetFiles(".");
foreach (String file in files)
{
fileNames.Add(System.IO.Path.GetFileName(file));
}
That will return the filename with extensions. You can then compare to your IList at that point.
Why bother going through all the trouble of building two lists when you could just check if each file exists in the directory? Effectively that is what your code is doing anyway.
foreach(string DspFle in DspFleName.Split(',')) {
string CheckPath = Path.Combine(ExportDirectory,DspFle[i]);
if (!File.Exists(CheckPath)) return false;
}
return true;
Maybe this is will do what you want?
if (DspFle == "None")
return true;
List<string> DspFle = DspFleName.Split(',');
List<string> ActualFiles = new List<string>();
foreach (string file in Directory.GetFiles(ExportDirectory)
{
DirectoryInfo di = new DirectoryInfo(file);
ActualFiles.Add(di.Name);
}
foreach (string file in DspFle)
{
if (!ActualFiles.Contains(dspFile))
return false;
}
return true;
DirectoryInfo will allow you to return the name of a file including the extension.

Categories

Resources