c# - 在不影响驱动器号的情况下清理 C# 中的文件路径
问题描述
我需要在 C# 中处理一些可能包含非法字符的文件路径,例如:
C:\path\something\output_at_13:26:43.txt
在该路径:
中,时间戳中的 s 使文件名无效,我想用另一个安全字符替换它们。
我已经在 SO 上搜索了解决方案,但它们似乎都基于以下内容:
path = string.Join("_", path.Split(Path.GetInvalidFileNameChars()));
或类似的解决方案。然而,这些解决方案并不好,因为它们搞砸了驱动器号,我得到了以下输出:
C_\path\something\output_at_13_26_43.txt
我尝试使用Path.GetInvalidPathChars()
但它仍然不起作用,因为它不包含:
非法字符,所以它不会替换文件名中的那些。
因此,在弄清楚这一点之后,我尝试这样做:
string dir = Path.GetDirectoryName(path);
string file = Path.GetFileName(path);
file = string.Join(replacement, file.Split(Path.GetInvalidFileNameChars()));
dir = string.Join(replacement, dir.Split(Path.GetInvalidPathChars()));
path = Path.Combine(dir, file);
但这也不好,因为:
文件名中的 s 似乎干扰了Path.GetFilename()
逻辑,它只返回 last 之后的最后一段:
,所以我丢失了路径。
我如何在没有 hacky 解决方案的情况下“正确”地做到这一点?
解决方案
您可以编写一个简单的清理程序来迭代每个字符并知道何时将冒号作为驱动器分隔符。这将捕获字母 AZ 后跟“:”的任意组合。它还将检测路径分隔符而不是逃避它们。它不会在输入字符串的开头检测空格,因此如果您的输入数据可能与它们一起出现,您必须先对其进行修剪或相应地修改消毒剂:
enum ParserState {
PossibleDriveLetter,
PossibleDriveLetterSeparator,
Path
}
static string SanitizeFileName(string input) {
StringBuilder output = new StringBuilder(input.Length);
ParserState state = ParserState.PossibleDriveLetter;
foreach(char current in input) {
if (((current >= 'a') && (current <= 'z')) || ((current >= 'A') && (current <= 'Z'))) {
output.Append(current);
if (state == ParserState.PossibleDriveLetter) {
state = ParserState.PossibleDriveLetterSeparator;
}
else {
state = ParserState.Path;
}
}
else if ((current == Path.DirectorySeparatorChar) ||
(current == Path.AltDirectorySeparatorChar) ||
((current == ':') && (state == ParserState.PossibleDriveLetterSeparator)) ||
!Path.GetInvalidFileNameChars().Contains(current)) {
output.Append(current);
state = ParserState.Path;
}
else {
output.Append('_');
state = ParserState.Path;
}
}
return output.ToString();
}
你可以在这里试试。
推荐阅读
- r - 如何根据其他列在新列上创建值?
- javascript - 如何从 MERN 技术栈中的数据库中检索最后添加的记录?
- r - 将 dgTMatrix 写入 HDF5 文件
- javascript - 我不能以角度调用javascript
- c++ - 如何在调试模式下打印程序中发生的事情
- javascript - 如何调整 IMG 元素的大小,使其在窗口大小发生变化时按比例位于窗口的同一位置?
- python - 如何在元组的每个值中添加引号?
- python - 为什么文件没有进入我的文件管理器中的正确文件夹?
- c# - Azure AD,无法针对邀请设置 AdditionalData
- javascript - 使用 fetch 在 C# 中向 API 发送“POST”时出现 405 错误