Làm cách nào để tìm phần mở rộng của tệp trong C #?


135

Trong ứng dụng web của tôi (asp.net, c #) Tôi đang tải lên tệp video trong một trang nhưng tôi chỉ muốn tải lên video flv. Làm cách nào để hạn chế khi tôi tải lên các video mở rộng khác?


1
Nếu có thể, bạn cũng muốn kiểm tra trên máy khách, để tránh tải lên không cần thiết.
Thilo

2
Có, nhưng hãy xem câu trả lời của tôi dưới đây - KHÔNG dựa vào kiểm tra phía khách hàng - nó sẽ bị phá vỡ sớm hay muộn. :)
ZombieSheep

4
Kiểm tra phía máy khách không phải là sự bảo vệ cho máy chủ của bạn, mà là sự thuận tiện cho người dùng.
Thilo

Được cấp. Tôi chỉ khuyên OP đừng dựa vào nó.
ZombieSheep

Câu trả lời:


269

Đường dẫn.GetExtension

string myFilePath = @"C:\MyFile.txt";
string ext = Path.GetExtension(myFilePath);
// ext would be ".txt"

8
Điều này cho phép ai đó chỉ đổi tên bất kỳ tệp * .flv và tải nó lên. Tùy thuộc vào yêu cầu của bạn là gì, bạn cũng có thể muốn kiểm tra loại MIME.
David Glenn

Không phải loại MIME thường được đặt theo phần mở rộng tên tệp?
Thilo

@Thilo, bạn đúng, nhưng tiện ích mở rộng có thể được thay đổi mà không thay đổi loại nội dung mime. Loại mime mô tả dữ liệu chứa trong tệp, vì vậy nó có thể được xử lý một cách thích hợp xem en.wikipedia.org/wiki/MIME
Mark Dickinson

2
Không, cách tốt hơn là kiểm tra nội dung tập tin. Nó là cần thiết để kiểm tra chữ ký flv.
Marat Faskhiev

Chỉ cần thêm vào điều này vì đây vẫn là một câu trả lời phổ biến - đối số loại MIME không an toàn như phần mở rộng vì cả hai đều có thể bị giả mạo. Một sự kết hợp của cả hai kiểm tra có thể là một giải pháp hợp lý nhưng cuối cùng nếu bảo mật là mối quan tâm thì nên có nhiều kiểm tra nghiêm ngặt hơn, ví dụ như chặn các tệp không dấu hoặc lấy mẫu nội dung.
James

21

Bạn có thể chỉ cần đọc luồng của một tập tin

using (var target = new MemoryStream())
{
    postedFile.InputStream.CopyTo(target);
    var array = target.ToArray();
}

5/6 chỉ mục đầu tiên sẽ cho bạn biết loại tệp. Trong trường hợp FLV 70, 76, 86, 1, 5 .

private static readonly byte[] FLV = { 70, 76, 86, 1, 5};

bool isAllowed = array.Take(5).SequenceEqual(FLV);

nếu isAllowedbằng truethì FLV của nó.

HOẶC LÀ

Đọc nội dung của tập tin

var contentArray = target.GetBuffer();
var content = Encoding.ASCII.GetString(contentArray);

Hai hoặc ba chữ cái đầu tiên sẽ cho bạn biết loại tệp.
Trong trường hợp FLV, "FLV ......"

content.StartsWith("FLV")

3
Điều này nên được đánh giá cao hơn. Nếu bạn thực sự muốn ứng dụng của bạn hoạt động và dữ liệu không đáng tin cậy, bạn nên kiểm tra lại từ đầu.
PRman

7

Tại máy chủ, bạn có thể kiểm tra loại MIME, tra cứu loại mime flv tại đây hoặc trên google.

Bạn nên kiểm tra xem loại mime là

video/x-flv

Nếu bạn đang sử dụng FileUpload trong C # chẳng hạn, bạn có thể làm

FileUpload.PostedFile.ContentType == "video/x-flv"

5

Tôi không chắc đây có phải là điều bạn muốn không:

Directory.GetFiles(@"c:\mydir", "*.flv");

Hoặc là:

Path.GetExtension(@"c:\test.flv")

4

Ngoài ra, nếu bạn có một FileInfo fi, bạn chỉ cần làm:

string ext = fi.Extension;

và nó sẽ giữ phần mở rộng của tệp (lưu ý: nó sẽ bao gồm ., vì vậy kết quả của những điều trên có thể là: .jpg .txtvân vân và vân vân ....


2

Bạn sẽ không thể hạn chế loại tệp mà người dùng tải lên ở phía máy khách [*]. Bạn sẽ chỉ có thể làm điều này ở phía máy chủ. Nếu người dùng tải lên một tệp không chính xác, bạn sẽ chỉ có thể nhận ra rằng một khi tệp được tải lên được tải lên. Không có cách nào đáng tin cậy và an toàn để ngăn người dùng tải lên bất kỳ định dạng tệp nào họ muốn.

[*] có, bạn có thể thực hiện tất cả các loại công cụ thông minh để phát hiện phần mở rộng tệp trước khi bắt đầu tải lên, nhưng đừng dựa vào nó. Ai đó sẽ nhận được xung quanh nó và tải lên bất cứ điều gì họ thích sớm hay muộn.


1
Mặc dù anh ta không thể ngăn chặn tin tặc tải lên những gì anh ta muốn, anh ta vẫn nên kiểm tra phía khách hàng để thuận tiện cho người dùng. Trình tải lên flash sẽ có thể kiểm tra loại tệp.
Thilo

1
OP đã không đề cập đến trình tải lên Flash (đó là 'trình tải lên được viết bằng Flash', thay vì 'người tải lên nội dung Flash'). Câu hỏi được gắn thẻ asp.net và thẻ c # và với các lựa chọn công nghệ đó, việc kiểm tra phía máy khách bị hạn chế và dễ dàng bị đánh bại. :)
ZombieSheep

Đối với một trang web tải lên video, anh ta nên có một cái gì đó tốt hơn ở phía khách hàng sau đó là một hình thức tải lên HTML. Tải lên nhiều MB mà không có thanh tiến trình là không vui.
Thilo

ok bạn nói rằng kiểm tra phía khách hàng không tốt lắm, làm thế nào tôi có thể kiểm tra phía máy chủ Ông ZombieSheep
Surya sasidhar

@Thilo - Tôi không thể đồng ý nhiều hơn, nhưng câu hỏi là về hình thức tải lên của ASP.net. Tùy thuộc vào OP cho dù anh ta nghĩ rằng đủ tốt hay không.
ZombieSheep


2

Kết thúc với ()

Tìm thấy một giải pháp thay thế tại DotNetPerls mà tôi thích hơn vì nó không yêu cầu bạn chỉ định đường dẫn. Đây là một ví dụ nơi tôi đã tạo ra một mảng với sự trợ giúp của một phương thức tùy chỉnh

        // This custom method takes a path 
        // and adds all files and folder names to the 'files' array
        string[] files = Utilities.FileList("C:\", "");
        // Then for each array item...
        foreach (string f in files)
        {
            // Here is the important line I used to ommit .DLL files:
            if (!f.EndsWith(".dll", StringComparison.Ordinal))
                // then populated a listBox with the array contents
                myListBox.Items.Add(f);
        }

2
string FileExtn = System.IO.Path.GetExtension(fpdDocument.PostedFile.FileName);

Phương pháp trên hoạt động tốt với firefox và IE, tôi có thể xem tất cả các loại tệp như zip, txt, xls, xlsx, doc, docx, jpg, png

nhưng khi tôi cố gắng tìm phần mở rộng của tập tin từ googlechrom, tôi đã thất bại.


2

Điều đáng nói là làm thế nào để loại bỏ phần mở rộng song song với việc có phần mở rộng:

var name = Path.GetFileNameWithoutExtension(fileFullName); // Get the name only

var extension = Path.GetExtension(fileFullName); // Get the extension only

0

Giải pháp này cũng giúp ích trong các trường hợp có nhiều hơn một tiện ích mở rộng như "Avishay.student.DB"

                FileInfo FileInf = new FileInfo(filePath);
                string strExtention = FileInf.Name.Replace(System.IO.Path.GetFileNameWithoutExtension(FileInf.Name), "");
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.