将 URI 路径转换为 ​​.NET 中的相对文件系统路径

发布于 2024-08-25 10:46:58 字数 138 浏览 8 评论 0原文

如何将绝对或相对 URI 路径(例如 /foo/bar.txt)转换为(分段)相应的相对文件系统路径(例如 foo\bar.txt) )在.NET 中?

我的程序不是 ASP.NET 应用程序。

How do I convert an absolute or relative URI path (e.g. /foo/bar.txt) to a (segmentwise) corresponding relative file system path (e.g. foo\bar.txt) in .NET?

My program is not an ASP.NET application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

太傻旳人生 2024-09-01 10:46:58

您是否已经尝试过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);
}

Have you already tried Server.MapPath?
or Uri.LocalPath property? Something like following :

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);
}
各自安好 2024-09-01 10:46:58

我想出了这种方法,可以从相对或绝对 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;

I figured out this way to produce a full absolute file system path from a relative or absolute URI and a base path.

With:

Uri basePathUri = new Uri(@"C:\abc\");

From a relative URI:

string filePath = new Uri(basePathUri, relativeUri).AbsolutePath;

From an absolute URI:

// baseUri is a URI used to derive a relative URI
Uri relativeUri = baseUri.MakeRelativeUri(absoluteUri);
string filePath = new Uri(basePathUri, relativeUri).AbsolutePath;
偏闹i 2024-09-01 10:46:58

您可以执行以下操作:

var localPath = Server.MapPath("/foo/bar.txt");

有关详细信息,请参阅 MSDN

You can do this:

var localPath = Server.MapPath("/foo/bar.txt");

See MSDN for details

无人接听 2024-09-01 10:46:58

由于后端或框架的更改,并非所有人都可以访问 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;
}

Not all have access to server.MapPath due to backend or framework changes, and there are lot's of way one of them is could be like this

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;
}

after this you just do:

switch (IsMappedTo(url))
{
    case FileLocation.NotSet:
        break;

    case FileLocation.Disk:
        break;

    case FileLocation.Resource:

        break;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文