我在莫干山 發表於 2021-5-16 22:41:00

C#常见的文件路径Api

<p>我们经常有遇到要处理文件路径的需求,那么一般我们常见的有几种:</p>
<ul>
<li>程序下面的文件</li>
<li>临时目录下的文件</li>
</ul>
<h2 id="获取程序下面的文件">获取程序下面的文件</h2>
<p>首先我们创建了实例解决方案:</p>
<p><img src="https://img2020.cnblogs.com/blog/1294271/202105/1294271-20210515131202879-883174015.jpg" alt="" loading="lazy"></p>
<p>其中调用链是:Main.Shell-&gt;FooALibrary-&gt;,首先我们将FooAFolder.txt和FooA.txt的文件属性设置生成操作为<strong>内容</strong>,复制到输出目录为<strong>始终复制</strong></p>
<p>那么我们有什么方法获取这两个文件的路径,我们可能会用到以下方法:</p>
<pre><code class="language-c#">var currentDomainBaseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var result = File.Exists(Path.Combine(currentDomainBaseDirectory, @"FooAFolder\FooAFolder.txt"))? "存在FooAFolder.txt": "不存在FooAFolder.txt";
Console.WriteLine(result);
result = File.Exists(Path.Combine(currentDomainBaseDirectory, @"FooA.txt"))? "存在FooA.txt": "不存在FooA.txt";
Console.WriteLine(result);
//存在FooAFolder.txt
//存在FooA.txt


var currentDirectory = System.Environment.CurrentDirectory;
result=File.Exists(Path.Combine(currentDirectory, @"FooAFolder\FooAFolder.txt")) ? "存在FooAFolder.txt" : "不存在FooAFolder.txt";
Console.WriteLine(result);
result = File.Exists(Path.Combine(currentDirectory, @"FooA.txt")) ? "存在FooA.txt" : "不存在FooA.txt";
Console.WriteLine(result);
//存在FooAFolder.txt
//存在FooA.txt
</code></pre>
<p>主要用到的两种方式就是:</p>
<ul>
<li>
<p>获取应用程序域的基目录:<code>AppDomain.CurrentDomain.BaseDirectory</code></p>
</li>
<li>
<p>获取当前工作目录的完全限定路径:<code>System.Environment.CurrentDirectory</code></p>
</li>
</ul>
<p>但是实际上以上两种方式不是最准和最稳的,</p>
<ul>
<li>System.Environment.CurrentDirectory:为当前工作路径,假设你用命令行方式打开应用程序,例如,c:/Ryzen ,那么当前工作路径则不是你安装到的那个路径,而是命令行的路径c:/Ryzen</li>
<li>AppDomain.CurrentDomain.BaseDirectory:为获取应用程序域的基目录,假如你有一个插件是在AppData临时目录下,那么你的插件只能获取到你安装应用程序的路径,而不是你插件的路径</li>
</ul>
<p>还有一种最稳的方式:</p>
<p>获取当前执行程序集的方式:<code>Assembly.GetExecutingAssembly().Location</code>(推荐方式)</p>
<pre><code class="language-c#">var mainExecuteDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
result = File.Exists(Path.Combine(mainExecuteDirectory, @"FooAFolder\FooAFolder.txt")) ? "存在FooAFolder.txt" : "不存在FooAFolder.txt";
Console.WriteLine(result);
result = File.Exists(Path.Combine(mainExecuteDirectory, @"FooA.txt")) ? "存在FooA.txt" : "不存在FooA.txt";
Console.WriteLine(result);
//存在FooAFolder.txt
//存在FooA.txt

//通过反射获取程序集
var fooAssembly = Assembly.GetAssembly(typeof(FooA));
var fooAExecuteDirectory = Path.GetDirectoryName(fooAssembly.Location);
result = File.Exists(Path.Combine(fooAExecuteDirectory, @"FooAFolder\FooAFolder.txt")) ? "存在FooAFolder.txt" : "不存在FooAFolder.txt";
Console.WriteLine(result);
result = File.Exists(Path.Combine(fooAExecuteDirectory, @"FooA.txt")) ? "存在FooA.txt" : "不存在FooA.txt";
Console.WriteLine(result);
Console.ReadLine();
//存在FooAFolder.txt
//存在FooA.txt
</code></pre>
<p>我们还能再拓展一下,我们在<code>FooA</code>和<code> FooB</code>添加如下代码:</p>
<pre><code class="language-c#">public static class FooB
{
    public static void GetExecutingAssemblyPath()
    {
      Console.WriteLine(Assembly.GetExecutingAssembly().Location);
    }

    public static void GetCallingAssemblyPath()
    {
      Console.WriteLine(Assembly.GetCallingAssembly().Location);
    }

    public static void GetEntryAssemblyPath()
    {
      Console.WriteLine(Assembly.GetEntryAssembly().Location);
    }

}


publicstatic class FooA
{
    public static void ExecuteFooBGetCallingAssemblyPath()
    {
      FooB.GetCallingAssemblyPath();
    }

    public static void ExecuteFooBGetExecutingAssemblyPath()
    {
      FooB.GetExecutingAssemblyPath();
    }
}

//调用
Console.WriteLine($"{nameof(FooA.ExecuteFooBGetExecutingAssemblyPath)}:");
FooA.ExecuteFooBGetExecutingAssemblyPath();

Console.WriteLine($"{nameof(FooA.ExecuteFooBGetCallingAssemblyPath)}:");
FooA.ExecuteFooBGetCallingAssemblyPath();

Console.WriteLine($"{nameof(FooB.GetExecutingAssemblyPath)}:");
FooB.GetExecutingAssemblyPath();

Console.WriteLine($"{nameof(FooB.GetCallingAssemblyPath)}:");
FooB.GetCallingAssemblyPath();

Console.WriteLine($"{nameof(FooB.GetEntryAssemblyPath)}:");
FooB.GetEntryAssemblyPath();

</code></pre>
<p>输出:</p>
<pre><code>ExecuteFooBGetExecutingAssemblyPath:
C:\Users\Ryzen\source\repos\CommonFilePathApiSample\Main.Shell\bin\Debug\netcoreapp3.1\FooBLibrary.dll

ExecuteFooBGetCallingAssemblyPath:
C:\Users\Ryzen\source\repos\CommonFilePathApiSample\Main.Shell\bin\Debug\netcoreapp3.1\FooALibrary.dll

GetExecutingAssemblyPath:
C:\Users\Ryzen\source\repos\CommonFilePathApiSample\Main.Shell\bin\Debug\netcoreapp3.1\FooBLibrary.dll

GetCallingAssemblyPath:
C:\Users\Ryzen\source\repos\CommonFilePathApiSample\Main.Shell\bin\Debug\netcoreapp3.1\Main.Shell.dll

GetEntryAssemblyPath:
C:\Users\Ryzen\source\repos\CommonFilePathApiSample\Main.Shell\bin\Debug\netcoreapp3.1\Main.Shell.dl
</code></pre>
<p>我们从上面可以知道以下两种的用法:</p>
<ul>
<li>获取入口程序集路径:<code>Assembly.GetEntryAssembly().Location</code>,<code>FooALibrary</code>和<code>FooBLibrary</code>的入口都是<code>Main.Shell</code></li>
<li>获取调用该程序集的程序集路径:<code>Assembly.GetCallingAssembly().Location</code>,当 <code>Main.Shell</code>调<code>FooBLibrary</code>,输出<code>Main.Shell</code>,<code>FooALibrary</code>调<code>FooBLibrary</code>,输出<code>FooALibrary</code></li>
</ul>
<p>因此,用程序集Assembly的一些路径Api是非常灵活且准确的</p>
<h2 id="获取临时目录下的文件">获取临时目录下的文件</h2>
<p>我们也经常会遇到需要获取临时目录路径的方式来放置一些程序临时文件,可以用下面方式获取:</p>
<pre><code class="language-c#">Console.WriteLine(Path.GetTempPath());
//C:\Users\Ryzen\AppData\Local\Temp\
</code></pre><br><br>
来源:https://www.cnblogs.com/ryzen/p/14771328.html
頁: [1]
查看完整版本: C#常见的文件路径Api