我的程序將從互聯網上取任意字符串並將它們用於文件名。有沒有簡單的方法來從這些字符串中刪除壞字符,還是需要爲此編寫一個自定義函數?有沒有在c#中使字符串文件路徑安全的方法?
回答
呃,我討厭它,當人們試圖猜測哪些字符是有效的。除了完全不可移植(總是考慮Mono)之外,之前的評論都錯過了更多25個無效字符。
'Clean just a filename
Dim filename As String = "salmnas dlajhdla kjha;dmas'lkasn"
For Each c In IO.Path.GetInvalidFileNameChars
filename = filename.Replace(c, "")
Next
'See also IO.Path.GetInvalidPathChars
這可能不會有太大的區別這個情況。 Windows錯誤只會抱怨少數人物。感謝您指出GetInvalidFileNameChars,但我之前沒有遇到過。我會記住它。 – BenAlabaster 2008-12-02 08:29:56
C#版本:foreach(Path.GetInvalidFileNameChars()中的var c){fileName = fileName.Replace(c,' - '); } – jcollum 2010-02-15 22:12:21
該解決方案如何處理名稱衝突?看起來,多個字符串可以匹配單個文件名(例如「Hell?」和「Hell *」)。如果你沒事的話只能刪除冒犯的字符然後罰款;否則你需要小心處理名稱衝突。 – 2011-06-13 09:55:21
我同意Grauenwolf,並會極力推薦Path.GetInvalidFileNameChars()
這裏是我的C#的貢獻:
string file = @"38?/.\}[+=n a882 a.a*/|n^%$ ad#(-))";
Array.ForEach(Path.GetInvalidFileNameChars(),
c => file = file.Replace(c.ToString(), String.Empty));
附: - 這比應該更神祕 - 我試圖簡潔。
如果你想快速去掉所有特殊字符,有時多個用戶可讀的文件名這個工作得很好:
string myCrazyName = "q`w^[email protected]#y$u%i^o&p*a(s)d_f-g+h=j{k}l|z:x\"c<v>b?n[m]q\\w;e'r,t.y/u";
string safeName = Regex.Replace(
myCrazyName,
"\W", /*Matches any nonword character. Equivalent to '[^A-Za-z0-9_]'*/
"",
RegexOptions.IgnoreCase);
// safeName == "qwertyuiopasd_fghjklzxcvbnmqwertyu"
下面是我現在使用(對於C#示例感謝jcollum)功能:
public static string MakeSafeFilename(string filename, char replaceChar)
{
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
{
filename = filename.Replace(c, replaceChar);
}
return filename;
}
爲了方便,我只是把它放在「助手」類中。
要去除無效字符:
static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
// Builds a string out of valid chars
var validFilename = new string(filename.Where(ch => !invalidFileNameChars.Contains(ch)).ToArray());
要更換無效字符:
static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
// Builds a string out of valid chars and an _ for invalid ones
var validFilename = new string(filename.Select(ch => invalidFileNameChars.Contains(ch) ? '_' : ch).ToArray());
要更換無效字符(並避免潛在的名稱衝突像地獄* VS地獄$):
static readonly IList<char> invalidFileNameChars = Path.GetInvalidFileNameChars();
// Builds a string out of valid chars and replaces invalid chars with a unique letter (Moves the Char into the letter range of unicode, starting at "A")
var validFilename = new string(filename.Select(ch => invalidFileNameChars.Contains(ch) ? Convert.ToChar(invalidFileNameChars.IndexOf(ch) + 65) : ch).ToArray());
我發現使用這是快速和容易理解:
<Extension()>
Public Function MakeSafeFileName(FileName As String) As String
Return FileName.Where(Function(x) Not IO.Path.GetInvalidFileNameChars.Contains(x)).ToArray
End Function
這工作,因爲一個string
是IEnumerable
作爲char
陣列,有一個string
構造函數的字符串,需要char
陣列。
static class Utils
{
public static string MakeFileSystemSafe(this string s)
{
return new string(s.Where(IsFileSystemSafe).ToArray());
}
public static bool IsFileSystemSafe(char c)
{
return !Path.GetInvalidFileNameChars().Contains(c);
}
}
這裏就是我剛剛加入到ClipFlair的(http://clipflair.codeplex.com)StringExtensions靜態類(Utils.Silverlight項目)的基礎上,從發佈的杜爾高拱壩上面的鏈接到相關的計算器問題收集信息:
public static string ReplaceInvalidFileNameChars(this string s, string replacement = "")
{
return Regex.Replace(s,
"[" + Regex.Escape(new String(System.IO.Path.GetInvalidPathChars())) + "]",
replacement, //can even use a replacement string of any length
RegexOptions.IgnoreCase);
//not using System.IO.Path.InvalidPathChars (deprecated insecure API)
}
這裏是我的版本:
static string GetSafeFileName(string name, char replace = '_') {
char[] invalids = Path.GetInvalidFileNameChars();
return new string(name.Select(c => invalids.Contains(c) ? replace : c).ToArray());
}
我不知道如何GetInvalidFileNameChars的結果進行計算,但「獲取」表明,它是無小事l,所以我緩存結果。此外,這隻會遍歷輸入字符串一次而不是多次,就像上面的解決方案遍歷一組無效字符,一次替換一個源字符串中的字符串。另外,我喜歡基於位置的解決方案,但我更喜歡替換無效的字符而不是刪除它們。最後,我的替換正好是一個字符,以避免在字符串迭代時將字符轉換爲字符串。
我說所有沒有做分析的人 - 這個只是「感覺」對我很好。 :)
private void textBoxFileName_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = CheckFileNameSafeCharacters(e);
}
/// <summary>
/// This is a good function for making sure that a user who is naming a file uses proper characters
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
internal static bool CheckFileNameSafeCharacters(System.Windows.Forms.KeyPressEventArgs e)
{
if (e.KeyChar.Equals(24) ||
e.KeyChar.Equals(3) ||
e.KeyChar.Equals(22) ||
e.KeyChar.Equals(26) ||
e.KeyChar.Equals(25))//Control-X, C, V, Z and Y
return false;
if (e.KeyChar.Equals('\b'))//backspace
return false;
char[] charArray = Path.GetInvalidFileNameChars();
if (charArray.Contains(e.KeyChar))
return true;//Stop the character from being entered into the control since it is non-numerical
else
return false;
}
爲什麼不將字符串轉換到Base64相當於是這樣的:如果你想將其轉換回
string UnsafeFileName = "salmnas dlajhdla kjha;dmas'lkasn";
string SafeFileName = Convert.ToBase64String(Encoding.UTF8.GetBytes(UnsafeFileName));
,所以你可以閱讀:
UnsafeFileName = Encoding.UTF8.GetString(Convert.FromBase64String(SafeFileName));
我用這從隨機描述中保存具有唯一名稱的PNG文件。
- 1. 使用sed替換文件中的所有路徑字符串
- 2. 在ruby中解析沒有文件路徑的excel文檔字符串
- 3. 有沒有驗證有效路徑/文件名的方法?
- 4. C#字符串文件路徑問題
- 5. 如何在c中使用子字符串與文件路徑#
- 6. 有沒有辦法使用字符串中的數據代替子進程中的文件路徑參數?
- 7. 如何檢查文件字符串路徑在java中有效
- 8. 有沒有空處理字符串的方法在C#
- 9. [C#]文件路徑中逐字字符串文字?
- 10. 在C中的字符串和路徑#
- 11. Windows文件路徑中特殊字符的安全缺陷
- 12. 結合在字符串c中的所有json路徑#
- 13. 爲什麼數組在C中的字符串後有路徑?
- 14. 有沒有辦法在C#中訪問字符串數組中的字符串?
- 15. 結合路徑,文件字符串和文字的路徑
- 16. 在C#中,是否有一種方法可以獲取嵌入資源文件的字符串路徑引用?
- 17. 如何在文件路徑中使用字符串或字符串的子串
- 18. 如何從字符串中提取沒有參數的文件的路徑?
- 19. TypeScript文件導入'路徑'沒有'路徑'包的地方
- 20. 有和沒有子域的路徑拆分字符串
- 21. tar文件沒有路徑
- 22. 有沒有辦法在VB6中完全擦除字符串?
- 23. web.config中的安全路徑/文件夾
- 24. 文件路徑有特殊字符\ N
- 25. 修剪文件路徑的最簡單,安全的方法
- 26. 是NReco線程安全嗎?有沒有解決方法?在c#
- 27. 來自NSDictionary的具有文件路徑的JSON字符串
- 28. 有沒有辦法在C中傳遞這樣的字符串?
- 29. 字符串文件路徑無法正常工作c#
- 30. 有沒有在nsstring中查找字符串的類或方法?
可能的重複[安全/允許的文件名清理器的.NET](http://stackoverflow.com/questions/1862993/safe-allowed-filename-cleaner-for-net) – N8allan 2015-07-02 22:51:38