c# - 在不破坏驱动器号的情况下清理 C# 中的文件路径

标签 c# filenames filepath

我需要在 C# 中处理一些可能包含非法字符的文件路径,例如:

C:\path\something\output_at_13:26:43.txt

在该路径中,时间戳中的 : 使文件名无效,我想用另一个安全字符替换它们。

我已经在 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);

但这也不好,因为文件名中的:好像干扰了Path.GetFilename()逻辑,它只返回最后一段在最后一个 : 之后,所以我丢失了部分路径。

如果没有骇人听闻的解决方案,我如何“正确地”做到这一点?

最佳答案

您可以编写一个简单的 sanitizer 程序来迭代每个字符并知道何时期望冒号作为驱动器分隔符。这个将捕获字母 A-Z 后跟“:”的任意组合。它还将检测路径分隔符并且不会转义它们。它不会检测输入字符串开头的空格,因此如果您的输入数据可能与它们一起出现,您将必须先修剪它或相应地修改 sanitizer :

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

您可以 try it out here .

关于c# - 在不破坏驱动器号的情况下清理 C# 中的文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53813397/

相关文章:

javascript - 当只有文件夹路径已知时,使用 javascript/jquery 从 url 获取当前文件名

c# - 从 ClaimsIdentity 检索 WindowsIdentity 的最佳方法是什么

c# - 如何将字节 block 读入结构

python - os.listdir() 使用什么方法获取目录中的文件列表?

python - 属性错误 : 'list' object has no attribute 'endswith'

azure - azure项目中的文件路径

r - Sys.glob 扩展

c# - 如何以及何时在 C# 中调用基类构造函数

c# - 从 $.post 传递数组到 Action

c++ - 全局变量的行为在不同的函数中有所不同