.NET

2009-12-07 8 views
6

के लिए सुरक्षित/अनुमत फ़ाइल नाम क्लीनर क्या मनमाने ढंग से स्ट्रिंग लेने के लिए .NET में कोई मानकीकृत/लाइब्ररिड/परीक्षण किया गया तरीका है और इसे इस तरह से मैंगल करें कि यह वैध फ़ाइल नाम का प्रतिनिधित्व करता है?.NET

अपना खुद का चार-प्रतिस्थापन फ़ंक्शन रोल करना काफी आसान है, लेकिन मुझे कुछ और मजबूत और पुनरुत्थान चाहिए।

उत्तर

9

यह समस्या उतनी सरल नहीं है जितनी आप सोच सकते हैं। Path.GetInvalidFileNameChars अवैध में वर्ण न केवल अवैध हैं, "पीआरएन" और "कॉन" जैसे कई फ़ाइल नाम हैं, जो विंडोज द्वारा आरक्षित हैं और बनाए नहीं जा सकते हैं। कोई भी नाम जो "।" में समाप्त होता है विंडोज़ में भी अवैध है। इसके अलावा, विभिन्न लंबाई सीमाएं हैं। पूरी सूची here पढ़ें।

यदि यह पर्याप्त नहीं है, तो अलग-अलग फाइल सिस्टम में अलग-अलग सीमाएं होती हैं, उदाहरण के लिए आईएसओ 9660 फाइलनाम "-" से शुरू नहीं हो सकते हैं लेकिन इसमें शामिल हो सकते हैं।

+0

यह * बिल्कुल * क्यों है, मैं एक साधारण रेगेक्स प्रतिस्थापन के साथ अपना खुद का रोलिंग क्यों नहीं करना चाहता था। धन्यवाद। –

1

क्या आपने Path.GetInvalidFileNameChars पर एक नज़र डाली है?

Really Useful .NET Classes Part 1 - System.IO.Path

+0

कि प्लस एक regex मेरी fallback है; आदर्श रूप में मुझे ऐसा कुछ चाहिए जो प्रतिस्थापन भी करता है। –

13

पर मिले आप की जाँच करने के लिए जो स्ट्रिंग के पात्रों अमान्य हैं Path.GetInvalidFileNameChars उपयोग कर सकते हैं, और या तो इस तरह के एक हायफ़न या के रूप में एक वैध चार करने के लिए उन्हें बदलने (यदि आप द्विदिश रूपांतरण की जरूरत है) द्वारा उन्हें स्थानापन्न % जैसे बचने वाले टोकन ने अपने यूनिकोड कोड के हेक्साडेसिमल प्रतिनिधित्व के बाद (मैंने वास्तव में इस तकनीक का उपयोग किया है लेकिन अभी कोड नहीं है)।

संपादित करें: बस अगर कोई दिलचस्पी लेता है, तो कोड है।

/// <summary> 
/// Escapes an object name so that it is a valid filename. 
/// </summary> 
/// <param name="fileName">Original object name.</param> 
/// <returns>Escaped name.</returns> 
/// <remarks> 
/// All characters that are not valid for a filename, plus "%" and ".", are converted into "%uuuu", where uuuu is the hexadecimal 
/// unicode representation of the character. 
/// </remarks> 
private string EscapeFilename(string fileName) 
{ 
    char[] invalidChars=Path.GetInvalidFileNameChars(); 

    // Replace "%", then replace all other characters, then replace "." 

    fileName=fileName.Replace("%", "%0025"); 
    foreach(char invalidChar in invalidChars) 
    { 
     fileName=fileName.Replace(invalidChar.ToString(), string.Format("%{0,4:X}", Convert.ToInt16(invalidChar)).Replace(' ', '0')); 
    } 
    return fileName.Replace(".", "%002E"); 
} 

/// <summary> 
/// Unescapes an escaped file name so that the original object name is obtained. 
/// </summary> 
/// <param name="escapedName">Escaped object name (see the EscapeFilename method).</param> 
/// <returns>Unescaped (original) object name.</returns> 
public string UnescapeFilename(string escapedName) 
{ 
    //We need to temporarily replace %0025 with %! to prevent a name 
    //originally containing escaped sequences to be unescaped incorrectly 
    //(for example: ".%002E" once escaped is "%002E%0025002E". 
    //If we don't do this temporary replace, it would be unescaped to "..") 

    string unescapedName=escapedName.Replace("%0025", "%!"); 
    Regex regex=new Regex("%(?<esc>[0-9A-Fa-f]{4})"); 
    Match m=regex.Match(escapedName); 
    while(m.Success) 
    { 
     foreach(Capture cap in m.Groups["esc"].Captures) 
      unescapedName=unescapedName.Replace("%"+cap.Value, Convert.ToChar(int.Parse(cap.Value, NumberStyles.HexNumber)).ToString()); 
     m=m.NextMatch(); 
    } 
    return unescapedName.Replace("%!", "%"); 
} 
+0

और -1 क्योंकि ...? – Konamiman

2

क्या आप "मनमानी स्ट्रिंग से उत्पन्न" के बारे में अधिक जानकारी प्रदान कर सकते हैं? आपकी कहानियों के आधार पर, ऐसा लगता है कि आप

क्या मनमानी स्ट्रिंग लेने और इसे इस तरह से मैंगल करने के लिए कोई तरीका है कि यह एक वैध फ़ाइल नाम का प्रतिनिधित्व करता है?

यदि ऐसा है तो कोई मानक फ़ंक्शन उपलब्ध नहीं है जिसे मैं जानता हूं। हालांकि आप निम्नलिखित का उपयोग कर सकते हैं जो चाल

public static string MakeValidFileName(string name) { 
    var invalid = Path.GetInvalidFileNameChars(); 
    var builder = new StringBuilder(); 
    foreach (var cur in name) { 
    builder.Append(invalid.Contains(cur) ? '_' : cur); 
    } 
    return builder.ToString(); 
} 
+0

अपने वाक्यांश का उपयोग करने के लिए प्रश्न संपादित करें ... धन्यवाद! –

0
सिर्फ मनोरंजन के लिए

, मैं एक पंक्ति में यह किया ..

Regex.Replace("http://codereview.stackexchange.com/questions/33851/how-can-i-improve-my-code/33857#33857", "[" + string.Join("", Path.GetInvalidFileNameChars().Select (p => p.ToString())) + "]", "_")