我遇到了AppDomain.CurrentDomain.BaseDirectory
的问题。
有时路径以'\'结尾,有时则不以'\'结尾。 我找不到理由。
如果我使用Path.Combine
会好的,但我想做Directory.GetParent
并产生不同的结果。
你有没有发现这个问题?
我可以采用不同的方式获取应用程序的父目录吗?
我目前的黑客是:
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
if (!baseDir.EndsWith("\\")) baseDir += "\\";
答案 0 :(得分:53)
您可以使用TrimEnd:
轻松确保所需的行为var baseDir = AppDomain.CurrentDomain.BaseDirectory.TrimEnd('\\') + "\\";
为了达到最佳效率(通过避免额外分配),在进行更改之前检查字符串是否以\
结尾,因为您并不总是需要:
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
if (!baseDir.EndsWith("\\"))
{
baseDir += "\\";
}
答案 1 :(得分:37)
就是这样,只要保持你的黑客。
在 plain Win32中有一个辅助函数PathAddBackslash。只需与目录分隔符保持一致:检查Path.DirectorySeparatorChar
和Path.AltDirectorySeparatorChar
,而不是硬代码\
。
这样的事情(请注意没有严重的错误检查):
string PathAddBackslash(string path)
{
// They're always one character but EndsWith is shorter than
// array style access to last path character. Change this
// if performance are a (measured) issue.
string separator1 = Path.DirectorySeparatorChar.ToString();
string separator2 = Path.AltDirectorySeparatorChar.ToString();
// Trailing white spaces are always ignored but folders may have
// leading spaces. It's unusual but it may happen. If it's an issue
// then just replace TrimEnd() with Trim(). Tnx Paul Groke to point this out.
path = path.TrimEnd();
// Argument is always a directory name then if there is one
// of allowed separators then I have nothing to do.
if (path.EndsWith(separator1) || path.EndsWith(separator2))
return path;
// If there is the "alt" separator then I add a trailing one.
// Note that URI format (file://drive:\path\filename.ext) is
// not supported in most .NET I/O functions then we don't support it
// here too. If you have to then simply revert this check:
// if (path.Contains(separator1))
// return path + separator1;
//
// return path + separator2;
if (path.Contains(separator2))
return path + separator2;
// If there is not an "alt" separator I add a "normal" one.
// It means path may be with normal one or it has not any separator
// (for example if it's just a directory name). In this case I
// default to normal as users expect.
return path + separator1;
}
为什么这么多代码?主要是因为如果用户输入/windows/system32
您不想获得/windows/system32\
而是/windows/system32/
,则详细信息就是魔鬼......
以更好的自我解释形式将所有内容整合在一起:
string PathAddBackslash(string path)
{
if (path == null)
throw new ArgumentNullException(nameof(path));
path = path.TrimEnd();
if (PathEndsWithDirectorySeparator())
return path;
return path + GetDirectorySeparatorUsedInPath();
bool PathEndsWithDirectorySeparator()
{
if (path.Length == 0)
return false;
char lastChar = path[path.Length - 1];
return lastChar == Path.DirectorySeparatorChar
|| lastChar == Path.AltDirectorySeparatorChar;
}
char GetDirectorySeparatorUsedInPath()
{
if (path.Contains(Path.AltDirectorySeparatorChar))
return Path.AltDirectorySeparatorChar;
return Path.DirectorySeparatorChar;
}
}
即使看起来如此,也不会处理URI格式file://
。 正确的东西再次执行其他.NET I / O函数所做的事情:不处理这种格式(并且可能抛出异常)。
作为替代方案,您始终可以导入Win32功能:
[DllImport("shlwapi.dll",
EntryPoint = "PathAddBackslashW",
SetLastError = True,
CharSet = CharSet.Unicode)]
static extern IntPtr PathAddBackslash(
[MarshalAs(UnmanagedType.LPTStr)]StringBuilder lpszPath);
答案 2 :(得分:5)
为了获得跨平台支持,可以使用此代码段:
using System.IO;
// Your input string.
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
// Get the absolut path from it (in case ones input is a relative path).
string fullPath = Path.GetFullPath(baseDir);
// Check for ending slashes, remove them (if any)
// and add a cross platform slash at the end.
string result = fullPath
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
+ Path.DirectorySeparatorChar;
作为一种方法:
private static string GetFullPathWithEndingSlashes(string input)
{
string fullPath = Path.GetFullPath(input);
return fullPath
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
+ Path.DirectorySeparatorChar;
}
或作为扩展方法:
public static string GetFullPathWithEndingSlashes(this string input)
{
return Path.GetFullPath(input)
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)
+ Path.DirectorySeparatorChar;
}
答案 3 :(得分:3)
我经常使用
public void receiveClick(View view) {
String takeButton = String.valueOf(view.getTag());
buttonPressed = Integer.parseInt(takeButton);
humanPlayerTurn(view);
aiPlayerTurn(view);
}
public void humanPlayerTurn(View view) {
if (noughtsTurn) {
System.out.println("Player picked: " + buttonPressed);
playerClick(view);
}
}
public void aiPlayerTurn(View view) {
if (aiValidPick()) {
playerClick(view);
} else {
aiPlayerTurn(view);
}
}
或者,如果我在同一个项目中需要多次或两次,我可能会使用这样的辅助函数:
path = Path.Combine(path, "x");
path = path.Substring(0, path.Length - 1);
答案 4 :(得分:2)
从 .NET Core 3.0 开始,可以使用 Path.EndsInDirectorySeparator()
:
string baseDir = AppDomain.CurrentDomain.BaseDirectory;
if (!Path.EndsInDirectorySeparator(baseDir))
{
baseDir += Path.DirectorySeparatorChar;
}
对于 Unix,它检查最后一个 char
是否为 '/'
。
对于 Windows,它检查最后一个 char
是文字 '\'
还是 '/'
。
答案 5 :(得分:0)
您可以简单地使用C# Path 库,有一个名为 TrimEndingDirectorySeparator 的方法,提供该方法的路径(如果路径末尾存在任何目录分隔符)会修剪,无论您的路径是虚拟的还是物理的,都可以使用C# $ 键,而不必使用旧的方法通过 String.Format 来创建路径字符串。路径中的 / 分隔符只需混合$和@,如下例所示。
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
string finalPath = $@"{Path.TrimEndingDirectorySeparator(baseDir)}/"