Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Often I need to clean a file name using Path.GetInvalidFileNameChars(), however I do not know of a way to search for any of the invalid letters (except by using Regex) in one pass.

public string LoopMethod()
{
    StringBuilder sb = new StringBuilder(fileName);
    foreach(var invalidChar in Path.GetInvalidFileNameChars())
    {
        sb.Replace(invalidChar, '_');
    }
    return sb.ToString();
}


Regex invalidCharsRegex;
public void RegexMethodInit()
{
    var invalidChars = Path.GetInvalidPathChars().Select(c => Regex.Escape(c.ToString())).ToString();
    invalidCharsRegex = new Regex(string.Join("|", invalidChars));
}

public string RegexMethod(string fileName)
{
    return invalidCharsRegex.Replace(fileName, "_");
}

Is one of those ways the "correct" way to to this or is there a better function I am missing?

share|improve this question
    
Related: forums.asp.net/t/1185961.aspx/1 –  Rice Flour Cookies Feb 21 '13 at 23:28
    
@Leonid Path.GetInvalidPathChars() returns a char[] of characters that are illegal in a file name. What I wanted to know is what is the proper way to clean a filename from the returned char[], is it to just loop like in my example, or is there a function that can take in a char[] and replace on a string in one operation? –  Scott Chamberlain Feb 22 '13 at 0:11
add comment

2 Answers 2

foreach(var c in Path.GetInvalidPathChars())
    path = path.replace(c, '_')

That's a bit inefficient as it can allocate a string on every itteration, but usually not a problem. Alternative:

var chars = Path.GetInvalidPathChars()
path = new string(path.Select(c => chars.Contains(c) ? '_' : c).ToArray())
share|improve this answer
    
Ah, your answer is better, except that you are not using a set. Using a set may speed things up or slow them down depending on the size of the array. Either way this function should run fast. –  Leonid Feb 23 '13 at 0:15
2  
Come to think of it, this code is doing File IO, any of these solutions is fine. They'll all be several levels of magnitude faster than doing File IO. –  Robert Wagner Feb 23 '13 at 10:50
add comment

This should be fairly fast (though I did not try to compile or run). The number of lines can probably be greatly reduced with LINQ.

public static IEnumerable<char> EnumerateFileNameAsChars(string fileName, char replaceChar = '_')
{
    var invalidChars = new HashSet<char>(Path.GetInvalidFileNameChars());
    foreach (char c in fileName)
    {
        if (invalidChars.Contains(c))
        {
            yield return replaceChar;
        }
        else
        {
            yield return c;
        }
    }
}

// And finally ...
public static string CleanUpFileName(string fileName, char replaceChar = '_')
{
    return String.Concat(EnumerateFileNameAsChars(fileName, replaceChar));
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.