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?

Surya sasidhar
źródło
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"
James
źródło
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")
Mukul Yadav
źródło
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"
Mark Dickinson
źródło
5

Nie jestem pewien, czy tego chcesz, ale:

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

Lub:

Path.GetExtension(@"c:\test.flv")
Carra
źródło
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 ....

Noctis
źródło
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.

ZombieSheep
źródło
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);
        }
megamaiku
źródło
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ę.

Papun Sahoo
źródło
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
Mohammed Noureldin
źródło
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), "");
avishay
źródło