开发者

Easiest way to check if an arbitrary String is a valid filename

In my application the user can enter a filename. Before processing I'd like to check if the input String is a valid filename on Windows Vista.

Whats the easiest way to do that?

By 开发者_JAVA技巧valid I'm reffering to legal and non-existing


Check whether filename.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 and !File.Exists(Path.Combine(someFolder, filename))


Check against GetInvalidFileNameChars():

var isValid = !string.IsNullOrEmpty(fileName) &&
              fileName.IndexOfAny(Path.GetInvalidFileNameChars()) < 0 &&
              !File.Exists(Path.Combine(sourceFolder, fileName));


If the file is going to be created, You should use a file dialog to specify the directory path. There's a short list of illegal characters for file names.

The only truly reliable way to tell if a file name is acceptable is to try it. Permissions is a morass.


I use this:

public static bool IsValidFileName(string name) {
    if(string.IsNullOrWhiteSpace(name)) return false;
    if(name.Length > 1 && name[1] == ':') {
        if(name.Length < 4 || name.ToLower()[0] < 'a' || name.ToLower()[0] > 'z' || name[2] != '\\') return false;
        name = name.Substring(3);
    }
    if(name.StartsWith("\\\\")) name = name.Substring(1);
    if(name.EndsWith("\\") || !name.Trim().Equals(name) || name.Contains("\\\\") ||
        name.IndexOfAny(Path.GetInvalidFileNameChars().Where(x=>x!='\\').ToArray()) >= 0) return false;
    return true;
}

Should take care of everything but reserved names, permissions, and length restrictions. This accepts both relative and absolute filenames.


This is just an idea. One should populate the exception list:

public static bool IsValidFilename(string filename)
{
    try
    {
        File.OpenRead(filename).Close();
    }
    catch (ArgumentException) { return false; }
    catch (Exception) { }
    return true;
}


For first part(Valid Filename), I use all ways and a temporary file creation to check if a file can be named as expected or throws an exception.
In some cases creating a file will not raise an exception until trying to delete it(eg: CON).
I also usa removePath arg to dictate it that file is just the name of file without its path.

using System.IO;
using System.Text;
private static readonly byte[] TestFileBytes = Encoding.ASCII.GetBytes(@"X");
public bool IsFileNameValid(string file, bool removePath = false)
{
    try
    {
        if (string.IsNullOrEmpty(file))
            return false;

        string fileNamePart = removePath ? Path.GetFileName(file) : file;
        if (fileNamePart.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
            return false;

        string fileName = Path.Combine(Path.GetTempPath(), fileNamePart);
        using FileStream fileStream = File.Create(fileName);
        {
            fileStream.Write(TestFileBytes, 0, TestFileBytes.Length);
        }

        File.Delete(fileName);
        return true;
    }
    catch
    {
        return false;
    }
}

If there is any denial of access to temp folder use a custom folder for creating test file.

This method will result false for . or .. or ... r any sequence of dot-only names in Windows, and also you can't create them manually, but those are not actually invalid names! those are uncreatable names for file or something like that ;).

And for next part(Not exists) just use: !File.Exists(yourFileNameWithPath).


If you create a DirectoryInfo for the file, it will throw an exception if there are any problems with the file/directory name, either invalid chars or length.

DirectoryInfo di = new DirectoryInfo(myFileName);
Console.WriteLine("This filename/path could be valid. The folder might not exist yet though.")
if(di.Exists)
    Console.WriteLine("This file already exist.")

Not great that it is using exceptions for flow control, but you can be confident that it is right. OTOH, if you already planned to give the calling code an exception, mission accomplished.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜