【发布时间】:2011-01-27 09:10:09
【问题描述】:
如何在 .NET 中将绝对或相对 URI 路径(例如 /foo/bar.txt)转换为(分段)对应的相对文件系统路径(例如 foo\bar.txt)?
我的程序不是 ASP.NET 应用程序。
【问题讨论】:
-
以相对 URI 路径为例对我来说可能更有意义。
如何在 .NET 中将绝对或相对 URI 路径(例如 /foo/bar.txt)转换为(分段)对应的相对文件系统路径(例如 foo\bar.txt)?
我的程序不是 ASP.NET 应用程序。
【问题讨论】:
由于后端或框架更改,并非所有人都可以访问 server.MapPath,并且有很多方式其中之一可能是这样的
public enum FileLocation
{
NotSet,
Disk,
Resource,
}
private static readonly string[] FileExtenstions = new[] {
".js"
,".ts"
,".vue"
,".css"
,".jpg"
,".png"
,".gif"
,".ico"
,".svg"
,".ttf"
,".eot"
,".ttf"
,".woff"
,".woff2"
,".mp4"
,".mp3"
,".emf"
};
public FileLocation IsMappedTo(Uri uri)
{
if (uri is null)
{
throw new ArgumentNullException(nameof(uri));
}
//make sure we support .net default URI contract
if (uri.IsFile)
return FileLocation.Disk;
//now assume you are looking in a web application
var path = uri.AbsolutePath;
if (path.Length == 0 || path.Equals("/",StringComparison.Ordinal) || path.Length< FileExtenstions.Min(s=>s.Length))
return FileLocation.NotSet;
//get the directory normally one would use IWebHostEnvironment.ContentRootPath different versions .net will have other methods
var dir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot");
//get all resources names from the assembly hosting this class out side if the loop from this assembly you can also use
//you can also use GetManifestResourceNames() to use the web application's assembly
var resourceNames = new HashSet<string>(this.GetType().Assembly.GetManifestResourceNames());
var entryAssembly = Assembly.GetEntryAssembly();
if (entryAssembly != null && entryAssembly != this.GetType().Assembly)
{
foreach (var entry in entryAssembly.GetManifestResourceNames())
{
if (string.IsNullOrEmpty(entry))
resourceNames.Add(entry);
}
}
for (var i = 0; i < FileExtenstions.Length; i++)
{
if (FileExtenstions[i].Equals(path[FileExtenstions[i].Length..], StringComparison.OrdinalIgnoreCase) || path.Contains(FileExtenstions[i], StringComparison.OrdinalIgnoreCase))
{
//exists on disk
if (File.Exists(Path.Combine(dir, path.Replace("/", @"\", StringComparison.Ordinal))))
return FileLocation.Disk;
//has a file as an embedded resource with the same name (ignores the path) so you might have duplicates names
if (resourceNames.Any(a => a.EndsWith(path.Split('/')[^1], StringComparison.OrdinalIgnoreCase)))
return FileLocation.Resource;
}
}
return FileLocation.NotSet;
}
在此之后,您只需:
switch (IsMappedTo(url))
{
case FileLocation.NotSet:
break;
case FileLocation.Disk:
break;
case FileLocation.Resource:
break;
}
【讨论】:
您是否已经尝试过Server.MapPath?
或Uri.LocalPath 财产?类似于以下内容:
string uriString = "file://server/filename.ext";
// Lesson learnt - always check for a valid URI
if(Uri.IsWellFormedUriString(uriString))
{
Uri uri = new Uri(uriString);
Console.WriteLine(uri.LocalPath);
}
【讨论】:
我想出了这种方法,可以从相对或绝对 URI 和基本路径生成完整的绝对文件系统路径。
与:
Uri basePathUri = new Uri(@"C:\abc\");
来自相对 URI:
string filePath = new Uri(basePathUri, relativeUri).AbsolutePath;
来自绝对 URI:
// baseUri is a URI used to derive a relative URI
Uri relativeUri = baseUri.MakeRelativeUri(absoluteUri);
string filePath = new Uri(basePathUri, relativeUri).AbsolutePath;
【讨论】:
【讨论】:
uri,所以如果不是网络,我很困惑,解释一下?
foo\bar.txt,我可以将其传递给Path.Combine 以创建绝对文件路径。
Path.Combine 以及像 `C:\abc` 这样的基本路径以形成绝对文件系统路径。关于术语,根据定义,相对路径不包含与其相关的信息。