我正在寻找一种简单的方法来编码/转义和解码/取消转义文件路径(文件路径中的非法字符"\/?:<>*|
)
HttpUtiliy.UrlEncode
做它的工作,除了它不编码*
字符。
我所能找到的只是用正则表达式转义,或者只是用_
我希望能够一致地编码/解码。
我想知道是否有预定义的方法可以做到这一点,或者我只需要编写一些代码来编码和另一部分来解码。
谢谢
我正在寻找一种简单的方法来编码/转义和解码/取消转义文件路径(文件路径中的非法字符"\/?:<>*|
)
HttpUtiliy.UrlEncode
做它的工作,除了它不编码*
字符。
我所能找到的只是用正则表达式转义,或者只是用_
我希望能够一致地编码/解码。
我想知道是否有预定义的方法可以做到这一点,或者我只需要编写一些代码来编码和另一部分来解码。
谢谢
我以前从未尝试过这样的事情,所以我把它放在一起:
static class PathEscaper
{
static readonly string invalidChars = @"""\/?:<>*|";
static readonly string escapeChar = "%";
static readonly Regex escaper = new Regex(
"[" + Regex.Escape(escapeChar + invalidChars) + "]",
RegexOptions.Compiled);
static readonly Regex unescaper = new Regex(
Regex.Escape(escapeChar) + "([0-9A-Z]{4})",
RegexOptions.Compiled);
public static string Escape(string path)
{
return escaper.Replace(path,
m => escapeChar + ((short)(m.Value[0])).ToString("X4"));
}
public static string Unescape(string path)
{
return unescaper.Replace(path,
m => ((char)Convert.ToInt16(m.Groups[1].Value, 16)).ToString());
}
}
它用 a 替换任何禁止字符,%
后跟它的 16 位十六进制表示,然后返回。(您可能会为您拥有的特定字符使用 8 位表示,但我认为我会在安全方面犯错。)
罗林的解决方案很好。但是有一个小问题。Rawling 方法生成的文件名可能包含“%”,如果使用此路径名作为 url,可能会导致一些错误。因此,我将 escapeChar 从 "%" 更改为 "__" 以确保生成的文件名与 url 约定兼容。
static class PathEscaper
{
static readonly string invalidChars = @"""\/?:<>*|";
static readonly string escapeChar = "__";
static readonly Regex escaper = new Regex(
"[" + Regex.Escape(escapeChar + invalidChars) + "]",
RegexOptions.Compiled);
static readonly Regex unescaper = new Regex(
Regex.Escape(escapeChar) + "([0-9A-Z]{4})",
RegexOptions.Compiled);
public static string Escape(string path)
{
return escaper.Replace(path,
m => escapeChar + ((short)(m.Value[0])).ToString("X4"));
}
public static string Unescape(string path)
{
return unescaper.Replace(path,
m => ((char)Convert.ToInt16(m.Groups[1].Value, 16)).ToString());
}
}
我一直在使用以下方法一段时间没有问题:
public static string SanitizeFileName(string filename) {
string regex = String.Format(@"[{0}]+", Regex.Escape(new string(Path.GetInvalidFileNameChars())));
return Regex.Replace(filename, regex, "_");
}