Cách dễ nhất để kiểm tra xem một chuỗi tùy ý có phải là tên tệp hợp lệ hay không


79

Trong ứng dụng của tôi, người dùng có thể nhập tên tệp. Trước khi xử lý, tôi muốn kiểm tra xem chuỗi đầu vào có phải là tên tệp hợp lệ trên Windows Vista hay không.

Cách dễ nhất để làm điều đó là gì?

Bằng cách hợp lệ, tôi đề cập đến hợp pháp và không tồn tại


Khi bạn nói tên tệp hợp lệ, bạn đang đề cập đến thực tế là tệp tồn tại hay bạn đang hỏi liệu tên đó có được hệ thống hoạt động cho phép không?
Jesse McCulloch

4
Có giá trị như ở (a) hiện có, (b) hợp pháp, hoặc (c) hợp pháp và không tồn tại?
Anthony Pegram

Sry, tôi nên làm rõ điều đó. Nó phải là (c) leagl và không tồn tại
RoflcoptrException

4
@roflcopter: Bạn chỉ cần xử lý lỗi trong khi tạo tệp. Bất kỳ hoạt động hệ thống tệp nào liên quan đến việc kiểm tra sự tồn tại đều có khả năng lỗi thời vào thời điểm nó trả về, vì hệ thống tệp là tài nguyên được chia sẻ toàn cầu.
Ben Voigt

1
@Roflcoptr: một tệp có cùng tên được tạo trong khoảng thời gian bạn kiểm tra tính hợp lệ và / hoặc sự tồn tại và thời điểm bạn thực sự cố gắng tạo nó không được coi là dòng chương trình bình thường. Bạn nên xác minh rằng tệp không tồn tại, nhưng khi bạn thực sự tạo tệp, kiến ​​thức đó đã cũ và chỉ nên được coi là phỏng đoán có học thức. Nó có khả năng vẫn đúng, nhưng nó không được đảm bảo .
Fredrik Mörk

Câu trả lời:


125

Kiểm tra xem filename.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0!File.Exists(Path.Combine(someFolder, filename))


1
Kiểm tra câu trả lời của Phil HUnt mặc dù; có vẻ như InvalidPathChars là một API đã lỗi thời và bạn nên sử dụng GetInvalidFileNameChars () để thay thế.
GendoIkari

3
<quote> Mảng được trả về từ phương thức này không được đảm bảo chứa tập hợp ký tự hoàn chỉnh không hợp lệ trong tên tệp và thư mục. </quote> Ngoài ra, thuộc tính đó không được dùng nữa.
Ben Voigt

4
phản ví dụ: "http://www.microsoft.com/"qua kiểm tra của bạn, nhưng không phải là một tên tập tin hợp lệ, như trên cho"::::"
Ben Voigt

3
Các ví dụ ngược lại khác: "" không hợp lệ và Chuỗi mới ('x', 1024) cũng không hợp lệ.
Rasmus Faber

2
@shellster Bạn có thể đổi tên tệp thành ".txt" trong windows explorer bằng cách yêu cầu explorer đổi tên tệp thành ".txt.". Chỉ cần một mẹo (hoặc ".txt ........" cũng sẽ hoạt động).
Robert McKee

37

Kiểm tra lại GetInvalidFileNameChars():

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

2
phản ví dụ: "http://www.microsoft.com/"qua kiểm tra của bạn, nhưng không phải là một tên tập tin hợp lệ, như trên cho"::::"
Ben Voigt

1
@Ben Voigt: Bạn đúng ::::là không chính xác được coi là hợp lệ. Tôi đã sửa câu trả lời để chỉ ra < 0thay vì == 0.
Phil Hunt

1
Ồ, tôi chỉ nhận thấy rằng bạn đang sử dụng GetInvalidFileNameChars, không GetInvalidPathCharsgiống như SLaks. Miễn là nó chỉ là một bài kiểm tra đối với tên tệp và không phải là tên tệp có đường dẫn, điều đó sẽ ổn.
Ben Voigt

@Ben Voigt: Vì OP đã hỏi về việc xác thực tên tệp và các đường dẫn chỉ ngầm xác nhận sự không tồn tại của tệp, tôi đã sử dụng GetInvalidFileNameChars:-)
Phil Hunt

11

Nếu tệp sẽ được tạo, Bạn nên sử dụng hộp thoại tệp để chỉ định đường dẫn thư mục. Có một danh sách ngắn các ký tự bất hợp pháp cho tên tệp.

Cách duy nhất thực sự đáng tin cậy để biết liệu tên tệp có được chấp nhận hay không là thử nó. Quyền là một thứ ngu ngốc.


Hộp thoại tệp là một con cá trích màu đỏ, nhưng +1 cho "cách duy nhất thực sự đáng tin cậy ... là thử nó".
Ben Voigt

1
Đã đồng ý. Ngay cả khi tên tệp không tồn tại và không chứa ký tự bất hợp pháp, có một số lý do khiến tệp không được tạo, rõ ràng nhất là thiếu quyền tạo đối với thư mục.
Bob Kaufman

Có những trường hợp bạn cần lưu vào một đường dẫn không xác định nhưng lại không muốn người dùng chọn đường dẫn chính xác. Trong những trường hợp này, hộp thoại tệp không khả thi.
Josh Noe

2

Tôi sử dụng cái này:

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;
}

Nên quan tâm đến mọi thứ trừ tên dành riêng, quyền và giới hạn độ dài. Điều này chấp nhận cả tên tệp tương đối và tuyệt đối.


0

Đây chỉ là một ý tưởng. Người ta nên điền danh sách ngoại lệ:

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

Nếu tệp chưa tồn tại thì sao?
Mike Cheel

@MikeCheel Mã chỉ trả về false nếu một ngoại lệ đối số được ném ra. Ngoại lệ đó chỉ được ném ra khi tên tệp không hợp lệ.
Burak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.