Как найти расширение файла на C #?

135

В моем веб-приложении (asp.net, С #) я загружаю видеофайл на страницу, но хочу загружать только видео в формате FLV. Как я могу ограничить загрузку других расширенных видео?

Сурья сашидхар
источник
1
Если возможно, вы также хотите проверить клиента, чтобы избежать ненужных загрузок.
Тило
2
Да, но посмотрите мой ответ ниже - НЕ полагайтесь на проверку на стороне клиента - рано или поздно ее обойдут. :)
ZombieSheep
4
Проверка на стороне клиента - это не защита вашего сервера, а удобство для пользователя.
Тило,
Предоставляется. Я просто советую ОП не полагаться на это.
ZombieSheep

Ответы:

269

Path.GetExtension

string myFilePath = @"C:\MyFile.txt";
string ext = Path.GetExtension(myFilePath);
// ext would be ".txt"
Джеймс
источник
8
Это позволяет кому-то просто переименовать любой файл * .flv и загрузить его. В зависимости от ваших требований вы также можете проверить тип MIME.
Дэвид Гленн,
Разве тип MIME обычно не устанавливается в соответствии с расширением имени файла?
Тило,
@Thilo, вы правы, но расширение можно изменить без изменения типа содержимого mime. Тип mime описывает данные, содержащиеся в файле, поэтому с ним можно обращаться соответствующим образом, см. En.wikipedia.org/wiki/MIME
Марк Дикинсон
2
Нет, лучше проверить содержимое файла. Надо проверить подпись flv.
Марат Фасхиев
Просто чтобы добавить к этому, поскольку это все еще популярный ответ - аргумент типа MIME так же небезопасен, как и расширение, поскольку оба могут быть подделаны. Комбинация обеих проверок, вероятно, является разумным решением, но в конечном итоге, если безопасность является проблемой, должны быть более строгие проверки, например, блокировка неподписанных файлов или выборка контента.
Джеймс
21

Вы можете просто прочитать поток файла

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

Первые 5/6 индексов сообщат вам тип файла. В случае FLV это 70, 76, 86, 1, 5 .

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

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

если isAllowedравно, trueто его FLV.

ИЛИ

Прочитать содержимое файла

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

Первые две / три буквы сообщают вам тип файла.
В случае FLV это "FLV ......"

content.StartsWith("FLV")
Мукул Ядав
источник
3
Это должно быть оценено выше. Если вы действительно хотите, чтобы ваше приложение работало и данные не являются надежными, вам следует проверить начало.
PRMan
7

На сервере вы можете проверить тип MIME, найти тип flv mime здесь или в Google.

Вы должны проверить, что тип пантомимы

video/x-flv

Если вы, например, использовали FileUpload на C #, вы могли бы сделать

FileUpload.PostedFile.ContentType == "video/x-flv"
Марк Дикинсон
источник
5

Я не уверен, что вы этого хотите, но:

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

Или:

Path.GetExtension(@"c:\test.flv")
Карра
источник
4

Кроме того, если у вас есть FileInfo fi, вы можете просто сделать:

string ext = fi.Extension;

и он будет содержать расширение файла (примечание: он будет включать в себя ., поэтому результатом вышеуказанного может быть: .jpg .txtи так далее ....

Ноктис
источник
2

Вы не сможете ограничить тип файла, который пользователь загружает на стороне клиента [*]. Вы сможете сделать это только на стороне сервера. Если пользователь загружает неправильный файл, вы сможете распознать это только после того, как файл будет загружен. Не существует надежного и безопасного способа остановить загрузку пользователем файла любого желаемого формата.

[*] Да, вы можете делать всевозможные хитрые вещи, чтобы определять расширение файла перед началом загрузки, но не полагайтесь на это. Кто-то рано или поздно обойдет это и загрузит все, что им нравится.

ZombieSheep
источник
1
Хотя он не может помешать хакеру загружать то, что он хочет, он все же должен проверять на стороне клиента для удобства пользователя. Загрузчики Flash должны иметь возможность проверять тип файла.
Тило
1
В OP не упоминаются загрузчики Flash (то есть «загрузчики, написанные во Flash», а не «загрузчики содержимого Flash»). Вопрос помечен тегами asp.net и C #, и с этими вариантами технологий проверка на стороне клиента ограничена и ее легко обойти. :)
ZombieSheep
Для сайта загрузки видео у него должно быть что-то получше на стороне клиента, чем форма загрузки HTML. Загрузка нескольких МБ без индикатора выполнения - это не весело.
Тило,
хорошо, вы говорите, что проверка на стороне клиента не так уж и хороша, как я могу проверить на стороне сервера Mr. ZombieSheep
Сурья сасидхар
@Thilo - Я не могу с этим согласиться, но вопрос в форме загрузки ASP.net. Решает OP, считает ли он этого достаточно хорошим или нет.
ZombieSheep
2

Вы можете проверить подпись .flv. Вы можете скачать спецификацию здесь:

http://www.adobe.com/devnet/flv/

См. Главу «Заголовок FLV».

Марат Фасхиев
источник
2

EndsWith ()

Нашел альтернативное решение в DotNetPerls, которое мне понравилось больше, потому что оно не требует указания пути. Вот пример, в котором я заполнил массив с помощью специального метода

        // 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
источник
2
string FileExtn = System.IO.Path.GetExtension(fpdDocument.PostedFile.FileName);

Вышеупомянутый метод отлично работает с Firefox и IE, я могу просматривать все типы файлов, такие как zip, txt, xls, xlsx, doc, docx, jpg, png.

но когда я пытаюсь найти расширение файла из googlechrome, мне не удалось.

Папун Саху
источник
2

Стоит упомянуть, как удалить расширение также параллельно с получением расширения:

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

var extension = Path.GetExtension(fileFullName); // Get the extension only
Мохаммед Нурелдин
источник
0

Это решение также помогает в случаях, когда используется более одного расширения, например Avishay.student.DB.

                FileInfo FileInf = new FileInfo(filePath);
                string strExtention = FileInf.Name.Replace(System.IO.Path.GetFileNameWithoutExtension(FileInf.Name), "");
Авишай
источник