Jak znaleźć rozszerzenie pliku w C #?


139

W mojej aplikacji sieci web (asp.net, c #) przekazuję plik wideo na stronie, ale chcę przekazać tylko pliki wideo flv. Jak mogę ograniczyć przesyłanie innych plików wideo z rozszerzeniami?


1
Jeśli to możliwe, chcesz również sprawdzić klienta, aby uniknąć niepotrzebnego przesyłania.
Thilo,

2
Tak, ale zobacz moją odpowiedź poniżej - NIE polegaj na sprawdzaniu po stronie klienta - prędzej czy później zostanie ominięta. :)
ZombieSheep,

4
Kontrola po stronie klienta nie jest ochroną serwera, ale wygodą dla użytkownika.
Thilo,

Zgoda. Radzę tylko OP, aby na tym nie polegał.
ZombieSheep

Odpowiedzi:


274

Path.GetExtension

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

8
To pozwala komuś zmienić nazwę dowolnego pliku * .flv i przesłać go. W zależności od Twoich wymagań możesz również chcieć sprawdzić typ MIME.
David Glenn,

Czy typ MIME zwykle nie jest ustawiany zgodnie z rozszerzeniem nazwy pliku?
Thilo,

@Thilo, masz rację, ale rozszerzenie można zmienić bez zmiany typu zawartości MIME. Typ MIME opisuje dane zawarte w pliku, więc można je odpowiednio obsłużyć, patrz en.wikipedia.org/wiki/MIME
Mark Dickinson,

2
Nie, lepszym sposobem jest sprawdzenie zawartości pliku. Konieczne jest sprawdzenie podpisu flv.
Marat Faskhiev,

Wystarczy dodać do tego, ponieważ nadal jest to popularna odpowiedź - argument typu MIME jest tak samo niebezpieczny jak rozszerzenie, ponieważ oba mogą zostać sfałszowane. Połączenie obu kontroli jest prawdopodobnie rozsądnym rozwiązaniem, ale ostatecznie, jeśli chodzi o bezpieczeństwo, powinny być bardziej rygorystyczne kontrole, np. Blokowanie niepodpisanych plików lub pobieranie próbek zawartości.
James

21

Możesz po prostu przeczytać strumień pliku

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

Pierwsze indeksy 5/6 wskażą typ pliku. W przypadku FLV to 70, 76, 86, 1, 5 .

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

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

jeśli isAllowedjest równe, trueto jego FLV.

LUB

Przeczytaj zawartość pliku

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

Pierwsze dwie / trzy litery określą typ pliku.
W przypadku pliku FLV jego „FLV ......”

content.StartsWith("FLV")

3
To powinno być ocenione wyżej. Jeśli naprawdę chcesz, aby Twoja aplikacja działała, a dane są niezaufane, powinieneś sprawdzić początek.
PRMan

7

Na serwerze możesz sprawdzić typ MIME, sprawdzić typ MIME flv tutaj lub w Google.

Powinieneś sprawdzić, czy typ MIME to

video/x-flv

Jeśli na przykład używasz FileUpload w C #, możesz to zrobić

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

5

Nie jestem pewien, czy tego chcesz, ale:

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

Lub:

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

4

Ponadto, jeśli masz FileInfo fi, możesz po prostu zrobić:

string ext = fi.Extension;

i będzie przechowywać rozszerzenie pliku (uwaga: będzie zawierać rozszerzenie ., więc wynikiem powyższego może być: .jpg .txti tak dalej ....


2

Nie będzie można ograniczyć typu pliku, który użytkownik przesyła po stronie klienta [*]. Będziesz mógł to zrobić tylko po stronie serwera. Jeśli użytkownik prześle nieprawidłowy plik, będziesz mógł to rozpoznać dopiero po przesłaniu pliku. Nie ma niezawodnego i bezpiecznego sposobu, aby uniemożliwić użytkownikowi przesyłanie plików w dowolnym formacie.

[*] tak, możesz zrobić wiele sprytnych rzeczy, aby wykryć rozszerzenie pliku przed rozpoczęciem przesyłania, ale nie polegaj na nim. Ktoś obejdzie to i wrzuci, co tylko zechce, wcześniej czy później.


1
Chociaż nie może powstrzymać hakera przed przesłaniem tego, czego chce, powinien nadal sprawdzić po stronie klienta dla wygody użytkownika. Osoby przesyłające Flash powinny mieć możliwość sprawdzenia typu pliku.
Thilo,

1
OP nie wspomniał o użytkownikach przesyłających Flash (to znaczy „przesyłających napisanych we Flashu”, a nie „przesyłających treści Flash”). Pytanie jest oznaczone tagami asp.net i C #, a dzięki tym opcjom technologicznym sprawdzanie po stronie klienta jest ograniczone i łatwe do pokonania. :)
ZombieSheep,

W przypadku witryny do przesyłania filmów powinien mieć coś lepszego po stronie klienta niż formularz przesyłania HTML. Przesyłanie wielu MB bez paska postępu nie jest zabawne.
Thilo,

ok, mówisz, że czek po stronie klienta nie jest zbyt dobry, jak mogę sprawdzić po stronie serwera Mr. ZombieSheep
Surya sasidhar

@Thilo - Nie mogę się bardziej zgodzić, ale pytanie dotyczy formularza przesyłania do ASP.net. To zależy od OP, czy uzna to za wystarczająco dobre, czy nie.
ZombieSheep


2

EndsWith ()

Znalazłem alternatywne rozwiązanie w DotNetPerls, które bardziej mi się podobało, ponieważ nie wymaga określenia ścieżki. Oto przykład, w którym wypełniłem tablicę za pomocą niestandardowej metody

        // 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);

Powyższa metoda działa dobrze z Firefox i IE, jestem w stanie przeglądać wszystkie typy plików, takie jak zip, txt, xls, xlsx, doc, docx, jpg, png

ale kiedy próbuję znaleźć rozszerzenie pliku z googlechrome, nie udało mi się.


2

Warto wspomnieć, jak usunąć rozszerzenie również równolegle z uzyskaniem rozszerzenia:

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

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

0

To rozwiązanie pomaga również w przypadku więcej niż jednego rozszerzenia, takiego jak „Avishay.student.DB”

                FileInfo FileInf = new FileInfo(filePath);
                string strExtention = FileInf.Name.Replace(System.IO.Path.GetFileNameWithoutExtension(FileInf.Name), "");
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.