Getting the relative path from the full path - c#

I have to get the path excluding the relative path from the full path,
say
The relative path is ,C:\User\Documents\
fullpath ,C:\User\Documents\Test\Folder2\test.pdf
I want to get only the path after the relative path i.e \Test\Folder2\test.pdf
how can i achieve this.
I am using C# as the programming language

You are not talking about relative, so i will call it partial path.
If you can be sure that the partial path is part of your full path its a simple string manipulation:
string fullPath = #"C:\User\Documents\Test\Folder2\test.pdf";
string partialPath = #"C:\User\Documents\";
string resultingPath = fullPath.Substring(partialPath.Length);
This needs some error checking though - it will fail when either fullPath or partialPath is null or both paths have the same length.

Hmmmm, but what if the case is different? Or one of the path uses short-names for its folders? The more complete solution would be...
public static string GetRelativePath(string fullPath, string containingFolder,
bool mustBeInContainingFolder = false)
{
var file = new Uri(fullPath);
if (containingFolder[containingFolder.Length - 1] != Path.DirectorySeparatorChar)
containingFolder += Path.DirectorySeparatorChar;
var folder = new Uri(containingFolder); // Must end in a slash to indicate folder
var relativePath =
Uri.UnescapeDataString(
folder.MakeRelativeUri(file)
.ToString()
.Replace('/', Path.DirectorySeparatorChar)
);
if (mustBeInContainingFolder && relativePath.IndexOf("..") == 0)
return null;
return relativePath;
}

To expand on Jan's answer, you could create an extension method on the string class (or the Path class if you wanted) such as:
namespace ExtensionMethods
{
public static class MyExtensions
{
public static string GetPartialPath(this string fullPath, string partialPath)
{
return fullPath.Substring(partialPath.Length)
}
}
}
And then use:
using ExtensionMethods;
string resultingPath = string.GetPartialPath(partialPath);
I haven't tested that this extension method works, but it should do.

Related

Get Last two folder's name from URL using C#

I have a URL and from which i need to get names after "bussiness" and Before the Page Name i.e. "paradise-villas-little.aspx" from below URL.
http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx
I am not getting how can i get this. i have tried the RawUrl, but it fetched the full. Please help me how can i do this.
UPDATE: This is a type of URL, i need to check it for dynamically.
You can create a little helper, and parse the URL from it's Uri Segments :
public static class Helper
{
public static IEnumerable<String> ExtractSegments(this Uri uri, String exclusiveStart)
{
bool startFound = false;
foreach (var seg in uri.Segments.Select(i => i.Replace(#"/","")))
{
if (startFound == false)
{
if (seg == exclusiveStart)
startFound = true;
}
else
{
if (!seg.Contains("."))
yield return seg;
}
}
}
}
And call it like this :
Uri uri = new Uri(#"http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx");
var found = uri.ExtractSegments("bussiness").ToList();
Then found contains "accommo" and "resort", and this method is extensible to any URL length, with or without file name at the end.
Nothing sophisticated in this implementation, just regular string operations:
string url = "http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx";
string startAfter = "business";
string pageName = "paradise-villas-little.aspx";
char delimiter = '/'; //not platform specific
var from = url.IndexOf(startAfter) + startAfter.Length + 1;
var to = url.Length - from - pageName.Length - 1;
var strings = url.Substring(from, to).Split(delimiter);
You may want to add validations though.
You have to use built-in string methods. The best is to use String Split.
String url = "http://test.com/anc/bussiness/accommo/resort/paradise-villas-little.aspx";
String[] url_parts = url.Split('/'); //Now you have all the parts of the URL all folders and page. Access the folder names from string array.
Hope this helps

IN c# how to get file names starting with a prefix from resource folder

how to access a text file based on its prefix
var str = GrvGeneral.Properties.Resources.ResourceManager.GetString(configFile + "_Nlog_Config");
var str1 = GrvGeneral.Properties.Resources.ResourceManager.GetObject(configFile + "_Nlog_Config");
where the configfile is the prefix of the resourcefile A & B .
Based on the configfile contents (prefix) the resource file A & B has to be accessed .
Use the DirectoryInfo class (documentation). Then you can call the GetFiles with a search pattern.
string searchPattern = "abc*.*"; // This would be for you to construct your prefix
DirectoryInfo di = new DirectoryInfo(#"C:\Path\To\Your\Dir");
FileInfo[] files = di.GetFiles(searchPattern);
Edit: If you have a way of constructing the actual file name you're looking for, you can go directly to the FileInfo class, otherwise you'll have to iterate through the matching files in my previous example.
Your question is rather vague...but it sounds like you want to get the text contents of an embedded resource. Usually you would do that using Assembly.GetManifestResourceStream. You can always use LINQ along with Assembly.GetManifestResourceNames() to find the name of an embedded file matching a pattern.
The ResourceManager class is more often used for automatically retrieving localized string resources, such as labels and error messages in different languages.
update: A more generalized example:
internal static class RsrcUtil {
private static Assembly _thisAssembly;
private static Assembly thisAssembly {
get {
if (_thisAssembly == null) { _thisAssembly = typeof(RsrcUtil).Assembly; }
return _thisAssembly;
}
}
internal static string GetNlogConfig(string prefix) {
return GetResourceText(#"Some\Folder\" + prefix + ".nlog.config");
}
internal static string FindResource(string pattern) {
return thisAssembly.GetManifestResourceNames()
.FirstOrDefault(x => Regex.IsMatch(x, pattern));
}
internal static string GetResourceText(string resourceName) {
string result = string.Empty;
if (thisAssembly.GetManifestResourceInfo(resourceName) != null) {
using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) {
result = new StreamReader(stream).ReadToEnd();
}
}
return result;
}
}
Using the example:
string aconfig = RsrcUtil.GetNlogConfig("a");
string bconfigname = RsrcUtil.FindResource(#"b\.\w+\.config$");
string bconfig = RsrcUtil.GetResourceText(bconfigname);

Replicating Directory.GetFiles(String, String) in Java

Overview
I'm in the process of porting a simple utility app over from C# into Java and as part of this I'm writing some helper methods for items where I prefer C#'s semantics. Once such case is Directory.GetFiles.
Current Code
import java.io.File;
import java.io.FilenameFilter;
public class Directory {
public static String[] GetFiles(String path) {
File directory = new File(path);
return directory.list(new FilenameFilter() {
#Override
public boolean accept(File dir, String filename) {
return new File(dir, filename).isFile();
}
});
}
}
Question
Whilst the above all seems fine, and replicates one of the GetFiles overloads, I'm stuck on how best to write a method that replicates the functionality of C#'s Directory.GetFiles(String, String).
This method should take a path string, as well as a searchPattern, which is used to return only files matching that particular pattern.
For example, each of the following should work:
// Used to get all JavaScript files
Directory.GetFiles("~/Documents/", "*.js");
// Get all CSS files in the styles sub-folder.
Directory.GetFiles("~/Documents/", "styles/*.css");
You could modify the pattern by placing a period before each asterisk and question mark, and then use this as a regular expression to determine which files you should return. So, you could write something like
public static String[] GetFiles(final String path, final String searchPattern) {
final Pattern re = Pattern.compile(searchPattern.replace("*", ".*").replace("?", ".?"));
return new File(path).list(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return new File(dir, name).isFile() && re.matcher(name).matches();
}
});
}
Using Adam Michalcin's answer as a base, I've come up with the following (note these methods return an array of absolute paths:
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;
public class Directory {
public static String[] GetFiles(String path) {
File directory = new File(path);
File[] matchingFiles = directory.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String filename) {
return new File(dir, filename).isFile();
}
});
ArrayList<String> files = new ArrayList<String>();
for (File file : matchingFiles) {
files.add(file.getAbsolutePath());
}
return (String[])files.toArray(new String[files.size()]);
}
public static String[] GetFiles(String path, final String searchPattern) {
// Split the searchPattern incase we have directories in there
ArrayList<String> pattern = new ArrayList<String>(Arrays.asList(searchPattern.split("/")));
// Take the last element out from the array, as this will be the file pattern
String filePattern = pattern.remove(pattern.size() - 1);
// Insert the base path into the remaining list
pattern.add(0, path);
// Now lets concat the lot to create a base path
path = Path.combine((String[])pattern.toArray(new String[pattern.size()]));
final Pattern regEx = Pattern.compile(filePattern.replace("*", ".*").replace("?", ".?"));
File directory = new File(path);
File[] matchingFiles = directory.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String filename) {
return new File(dir, filename).isFile() && regEx.matcher(filename).matches();
}
});
ArrayList<String> files = new ArrayList<String>();
for (File file : matchingFiles) {
files.add(file.getAbsolutePath());
}
return (String[])files.toArray(new String[files.size()]);
}
}
This also utilizes another helper I've put in place (Path.combine):
import java.io.File;
public class Path {
public static String combine(String... paths)
{
File file = new File(paths[0]);
for (int i = 1; i < paths.length ; i++) {
file = new File(file, paths[i]);
}
return file.getPath();
}
}
Usage
Directory.GetFiles("/Users/beardtwizzle/", "/Documents/javascripts/*.js");
This does still the other character problem that Bruno Silva mentions. So will try and bake a fix in for that too.

Getting URL from file path in IHttpHandler (Generic handler)

In my IHttpHandler class (for an .ashx page), I want to search a directory for certain files, and return relative urls. I can get the files, no problem:
string dirPath = context.Server.MapPath("~/mydirectory");
string[] files = Directory.GetFiles(dirPath, "*foo*.txt");
IEnumerable<string> relativeUrls = files.Select(f => WHAT GOES HERE? );
What is the easiest way to convert file paths to relative urls? If I were in an aspx page, I could say this.ResolveUrl(). I know I could do some string parsing and string replacement to get the relative url, but is there some built-in method that will take care of all of that for me?
Edit: To clarify, without doing my own string parsing, how do I go from this:
"E:\Webs\WebApp1\WebRoot\mydirectory\foo.txt"
to this:
"/mydirectory/foo.txt"
I'm looking for an existing method like:
public string GetRelativeUrl(string filePath) { }
I can imagine a lot of people having this question... My solution is:
public static string ResolveRelative(string url)
{
var requestUrl = context.Request.Url;
string baseUrl = string.Format("{0}://{1}{2}{3}",
requestUrl.Scheme, requestUrl.Host,
(requestUrl.IsDefaultPort ? "" : ":" + requestUrl.Port),
context.Request.ApplicationPath);
if (toresolve.StartsWith("~"))
{
return baseUrl + toresolve.Substring(1);
}
else
{
return new Uri(new Uri(baseUrl), toresolve).ToString();
}
}
update
Or from filename to virtual path (haven't tested it; you might need some code similar to ResoveRelative above as well... let me know if it works):
public static string GetUrl(string filename)
{
if (filename.StartsWith(context.Request.PhysicalApplicationPath))
{
return context.Request.ApplicationPath +
filename.Substring(context.Request.PhysicalApplicationPath.Length);
}
else
{
throw new ArgumentException("Incorrect physical path");
}
}
try System.Web.Hosting.HostingEnvironment.MapPath method, its static and can be accessed everywhere in web application.

Absolute path back to web-relative path

If I have managed to locate and verify the existence of a file using Server.MapPath and I now want to send the user directly to that file, what is the fastest way to convert that absolute path back into a relative web path?
Perhaps this might work:
String RelativePath = AbsolutePath.Replace(Request.ServerVariables["APPL_PHYSICAL_PATH"], String.Empty);
I'm using c# but could be adapted to vb.
Wouldn't it be nice to have Server.RelativePath(path)?
well, you just need to extend it ;-)
public static class ExtensionMethods
{
public static string RelativePath(this HttpServerUtility srv, string path, HttpRequest context)
{
return path.Replace(context.ServerVariables["APPL_PHYSICAL_PATH"], "~/").Replace(#"\", "/");
}
}
With this you can simply call
Server.RelativePath(path, Request);
I know this is old but I needed to account for virtual directories (per #Costo's comment). This seems to help:
static string RelativeFromAbsolutePath(string path)
{
if(HttpContext.Current != null)
{
var request = HttpContext.Current.Request;
var applicationPath = request.PhysicalApplicationPath;
var virtualDir = request.ApplicationPath;
virtualDir = virtualDir == "/" ? virtualDir : (virtualDir + "/");
return path.Replace(applicationPath, virtualDir).Replace(#"\", "/");
}
throw new InvalidOperationException("We can only map an absolute back to a relative path if an HttpContext is available.");
}
I like the idea from Canoas. Unfortunately I had not "HttpContext.Current.Request" available (BundleConfig.cs).
I changed the methode like this:
public static string RelativePath(this HttpServerUtility srv, string path)
{
return path.Replace(HttpContext.Current.Server.MapPath("~/"), "~/").Replace(#"\", "/");
}
If you used Server.MapPath, then you should already have the relative web path. According to the MSDN documentation, this method takes one variable, path, which is the virtual path of the Web server. So if you were able to call the method, you should already have the relative web path immediately accessible.
For asp.net core i wrote helper class to get pathes in both directions.
public class FilePathHelper
{
private readonly IHostingEnvironment _env;
public FilePathHelper(IHostingEnvironment env)
{
_env = env;
}
public string GetVirtualPath(string physicalPath)
{
if (physicalPath == null) throw new ArgumentException("physicalPath is null");
if (!File.Exists(physicalPath)) throw new FileNotFoundException(physicalPath + " doesn't exists");
var lastWord = _env.WebRootPath.Split("\\").Last();
int relativePathIndex = physicalPath.IndexOf(lastWord) + lastWord.Length;
var relativePath = physicalPath.Substring(relativePathIndex);
return $"/{ relativePath.TrimStart('\\').Replace('\\', '/')}";
}
public string GetPhysicalPath(string relativepath)
{
if (relativepath == null) throw new ArgumentException("relativepath is null");
var fileInfo = _env.WebRootFileProvider.GetFileInfo(relativepath);
if (fileInfo.Exists) return fileInfo.PhysicalPath;
else throw new FileNotFoundException("file doesn't exists");
}
from Controller or service inject FilePathHelper and use:
var physicalPath = _fp.GetPhysicalPath("/img/banners/abro.png");
and versa
var virtualPath = _fp.GetVirtualPath(physicalPath);

Categories

Resources