2009-03-27 5 views
11

Мои WPF приложение получает файл от пользователя с Microsoft.Win32.OpenFileDialog() ...Как определить тип содержимого файла в .NET?

Private Sub ButtonUpload_Click(...) 
    Dim FileOpenStream As Stream = Nothing 
    Dim FileBox As New Microsoft.Win32.OpenFileDialog() 
    FileBox.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) 
    FileBox.Filter = "Pictures (*.jpg;*.jpeg;*.gif;*.png)|*.jpg;*.jpeg;*.gif;*.png|" & _ 
        "Documents (*.pdf;*.doc;*.docx;)|*.pdf;*.doc;*.docx;|" & _ 
        "All Files (*.*)|*.*" 
    FileBox.FilterIndex = 1 
    FileBox.Multiselect = False 
    Dim FileSelected As Nullable(Of Boolean) = FileBox.ShowDialog(Me) 
    If FileSelected IsNot Nothing AndAlso FileSelected.Value = True Then 
     Try 
      FileOpenStream = FileBox.OpenFile() 
      If (FileOpenStream IsNot Nothing) Then 
       Dim ByteArray As Byte() 
       Using br As New BinaryReader(FileOpenStream) 
        ByteArray = br.ReadBytes(FileOpenStream.Length) 
       End Using 
       Dim z As New ZackFile 
       z.Id = Guid.NewGuid 
       z.FileData = ByteArray 
       z.FileSize = CInt(ByteArray.Length) 
       z.FileName = FileBox.FileName.Split("\").Last 
       z.DateAdded = Now 
       db.AddToZackFile(z) 
       db.SaveChanges() 
      End If 
     Catch Ex As Exception 
      MessageBox.Show("Cannot read file from disk. " & Ex.Message, "Fail", MessageBoxButton.OK, MessageBoxImage.Error) 
     Finally 
      If (FileOpenStream IsNot Nothing) Then 
       FileOpenStream.Close() 
      End If 
     End Try 
    End If 
End Sub 

И мое приложение ASP.NET MVC служит его для загрузки на веб-сайте с FileStreamResult(). ..

Public Class ZackFileController 
    Inherits System.Web.Mvc.Controller 

    Function Display(ByVal id As Guid) As FileStreamResult 
     Dim db As New EfrDotOrgEntities 
     Dim Model As ZackFile = (From z As ZackFile In db.ZackFile _ 
           Where z.Id = id _ 
           Select z).First 
     Dim ByteArray As Byte() = Model.ImageData 
     Dim FileStream As System.IO.MemoryStream = New System.IO.MemoryStream(ByteArray) 
     Dim ContentType As String = ????? 
     Dim f As New FileStreamResult(FileStream, ContentType) 
     f.FileDownloadName = Model.FileName 
     Return f 
    End Function 

End Class 

Но FileStreamResult() нуждается в строке типа содержимого. Как узнать правильный тип содержимого моего файла?

+0

Как функция отображения используется внутри страницы? – shahkalpesh

+0

Нет страницы. Это класс контроллера ASP.NET MVC. Дисплей является одним из его видов. Но поскольку этот вид возвращает FileStreamResult, а не ViewResult, он не имеет ASPX-страницы. –

ответ

15

я заменил столбец FileExtension в моей таблице базы данных с колонкой ContentType.

Я заполняю его, когда загружаю файл.

Private Sub ButtonUpload_Click(...) 
    ... 
    Dim FileExtension As String = "." + FileBox.FileName.Split(".").Last.ToLower 
    z.ContentType = ContentType(FileExtension) 
    ... 
End Sub 

я определить тип содержимого с помощью этой функции:

Function ContentType(ByVal FileExtension As String) As String 
    Dim d As New Dictionary(Of String, String) 
    'Images' 
    d.Add(".bmp", "image/bmp") 
    d.Add(".gif", "image/gif") 
    d.Add(".jpeg", "image/jpeg") 
    d.Add(".jpg", "image/jpeg") 
    d.Add(".png", "image/png") 
    d.Add(".tif", "image/tiff") 
    d.Add(".tiff", "image/tiff") 
    'Documents' 
    d.Add(".doc", "application/msword") 
    d.Add(".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document") 
    d.Add(".pdf", "application/pdf") 
    'Slideshows' 
    d.Add(".ppt", "application/vnd.ms-powerpoint") 
    d.Add(".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation") 
    'Data' 
    d.Add(".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") 
    d.Add(".xls", "application/vnd.ms-excel") 
    d.Add(".csv", "text/csv") 
    d.Add(".xml", "text/xml") 
    d.Add(".txt", "text/plain") 
    'Compressed Folders' 
    d.Add(".zip", "application/zip") 
    'Audio' 
    d.Add(".ogg", "application/ogg") 
    d.Add(".mp3", "audio/mpeg") 
    d.Add(".wma", "audio/x-ms-wma") 
    d.Add(".wav", "audio/x-wav") 
    'Video' 
    d.Add(".wmv", "audio/x-ms-wmv") 
    d.Add(".swf", "application/x-shockwave-flash") 
    d.Add(".avi", "video/avi") 
    d.Add(".mp4", "video/mp4") 
    d.Add(".mpeg", "video/mpeg") 
    d.Add(".mpg", "video/mpeg") 
    d.Add(".qt", "video/quicktime") 
    Return d(FileExtension) 
End Function 

Это работает, но это, кажется, безвкусный.

+3

Вы, вероятно, должны использовать оператор switch вместо создания нового словаря каждый раз, когда вы вызываете 'ContentType'. Кроме того, существует метод Path.GetExtension, поэтому вам не нужно разделить имя файла вручную. – StriplingWarrior

+0

VB.Net 10 немного лучше ... Dim d As New Dictionary (Of String, String) Из { {".bmp", "image/bmp"}, {".gif", "image/gif "}, {" .jpeg "," image/jpeg "}} 'и т. Д. – JoelFan

+0

@StriplingWarrior или сохранить один статический словарь. Если этот метод часто используется и поддерживает большую часть расширений файлов, я думаю, что скорость будет немного меньше. –

2

Похоже, у вас все еще есть имя файла, когда вы выбираете тип контента. Вы можете выбрать правильный тип mime для расширения файла или по умолчанию использовать что-то вроде «application/base64».

Предполагая, что человек скачиванием будет использовать веб-браузер, попробуйте придерживаться распространенных: MIME Types Known By IE

+0

+1 для ссылки –

+0

Это не является надежным для всего, что пройдет через проверку пера. Я мог бы загрузить .exe, переименованный в .docx, используя этот пример. –

6

Я использую раздел заказа конфигурации в файле web.config (я оставляю задачу написания раздела пользовательских настроек для вас):

<configSections> 
    <section name="mimeTypeMappings" type="MySoftwareLol.MimeTypeMappingSection, MySoftwareLol"/> 
</configSections> 

<mimeTypeMappings> 
    <MimeTypes> 
     <MimeType Type="application/mac-binhex40" Extensions=".hqx"/> 
     <MimeType Type="application/msword" Extensions=".doc"/> 
     <MimeType Type="application/pdf" Extensions=".pdf"/> 
     <MimeType Type="application/postscript" Extensions=".ai;.eps;.ps"/> 
     <MimeType Type="application/rtf" Extensions=".rtf"/> 
     <MimeType Type="application/vnd.ms-excel" Extensions=".xla;.xlc;.xlm;.xls;.xlt;.xlw"/> 
     <MimeType Type="application/vnd.ms-outlook" Extensions=".msg"/> 
     <MimeType Type="application/vnd.ms-powerpoint" Extensions=".pot;.pps;.ppt"/> 
     <MimeType Type="application/vnd.ms-works" Extensions=".wcm;.wdb;.wks;.wps"/> 
     <MimeType Type="application/x-compress" Extensions=".z"/> 
     <MimeType Type="application/x-compressed" Extensions=".tgz"/> 
     <MimeType Type="application/x-gzip" Extensions=".gz"/> 
     <MimeType Type="application/x-msaccess" Extensions=".mdb"/> 
     <MimeType Type="application/x-msmetafile" Extensions=".wmf"/> 
     <MimeType Type="application/x-mspublisher" Extensions=".pub"/> 
     <MimeType Type="application/x-msschedule" Extensions=".scd"/> 
     <MimeType Type="application/x-msterminal" Extensions=".trm"/> 
     <MimeType Type="application/x-mswrite" Extensions=".wri"/> 
     <MimeType Type="application/x-tar" Extensions=".tar"/> 
     <MimeType Type="application/zip" Extensions=".zip"/> 
     <MimeType Type="audio/basic" Extensions=".au;.snd"/> 
     <MimeType Type="audio/mid" Extensions=".mid;.rmi"/> 
     <MimeType Type="audio/mpeg" Extensions=".mp3"/> 
     <MimeType Type="audio/x-aiff" Extensions=".aif;.aifc;.aiff"/> 
     <MimeType Type="audio/x-pn-realaudio" Extensions=".ra;.ram"/> 
     <MimeType Type="audio/x-wav" Extensions=".wav"/> 
     <MimeType Type="image/bmp" Extensions=".bmp"/> 
     <MimeType Type="image/gif" Extensions=".gif"/> 
     <MimeType Type="image/jpeg" Extensions=".jpe;.jpeg;.jpg"/> 
     <MimeType Type="image/pipeg" Extensions=".jfif"/> 
     <MimeType Type="image/tiff" Extensions=".tif;.tiff"/> 
     <!--By default, sends HTML documents as plain text; sending it as text/html may pose security risks--> 
     <!--If you wish to accept the risks, uncomment the following two lines and comment out the third.--> 
     <!--<MimeType Type="text/html" Extensions=".mht;.html;.htm"/>--> 
     <!--<MimeType Type="text/plain" Extensions=".txt"/>--> 
     <MimeType Type="text/plain" Extensions=".txt;.html;.htm"/> 
     <MimeType Type="text/richtext" Extensions=".rtx"/> 
     <MimeType Type="text/tab-separated-values" Extensions=".tsv"/> 
     <MimeType Type="video/mpeg" Extensions=".mp2;.mpa;.mpe;.mpeg;.mpg;.mpv2"/> 
     <MimeType Type="video/quicktime" Extensions=".mov;.qt"/> 
     <MimeType Type="video/x-la-asf" Extensions=".lsf;.lsx;.asf;.asr;.asx;"/> 
     <MimeType Type="video/x-msvideo" Extensions=".avi"/> 
    </MimeTypes> 
    </mimeTypeMappings> 

Я использую Path.GetExtension() и карту, что к одному из типы, перечисленные в расширениях.

4

Я создал класс помощников C#, основанный на ответе Заков.

/// <summary> 
/// Helps with Mime Types 
/// </summary> 
public static class MimeTypesHelper 
{ 
    /// <summary> 
    /// Returns the content type based on the given file extension 
    /// </summary> 
    public static string GetContentType(string fileExtension) 
    { 
     var mimeTypes = new Dictionary<String, String> 
      { 
       {".bmp", "image/bmp"}, 
       {".gif", "image/gif"}, 
       {".jpeg", "image/jpeg"}, 
       {".jpg", "image/jpeg"}, 
       {".png", "image/png"}, 
       {".tif", "image/tiff"}, 
       {".tiff", "image/tiff"}, 
       {".doc", "application/msword"}, 
       {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, 
       {".pdf", "application/pdf"}, 
       {".ppt", "application/vnd.ms-powerpoint"}, 
       {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"}, 
       {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}, 
       {".xls", "application/vnd.ms-excel"}, 
       {".csv", "text/csv"}, 
       {".xml", "text/xml"}, 
       {".txt", "text/plain"}, 
       {".zip", "application/zip"}, 
       {".ogg", "application/ogg"}, 
       {".mp3", "audio/mpeg"}, 
       {".wma", "audio/x-ms-wma"}, 
       {".wav", "audio/x-wav"}, 
       {".wmv", "audio/x-ms-wmv"}, 
       {".swf", "application/x-shockwave-flash"}, 
       {".avi", "video/avi"}, 
       {".mp4", "video/mp4"}, 
       {".mpeg", "video/mpeg"}, 
       {".mpg", "video/mpeg"}, 
       {".qt", "video/quicktime"} 
      }; 

     // if the file type is not recognized, return "application/octet-stream" so the browser will simply download it 
     return mimeTypes.ContainsKey(fileExtension) ? mimeTypes[fileExtension] : "application/octet-stream"; 
    } 
} 

Вы могли бы, конечно, хотите сохранить mimeTypes живым для будущих запросов. Это всего лишь отправная точка.

19

Существует класс MimeMapping в .NET 4.5

http://msdn.microsoft.com/en-us/library/system.web.mimemapping.aspx

+0

Блестящий, намного лучший, чем я, вытаскивая информацию и создавая таблицу MimeMapping. – GibralterTop

+0

Но ... класс MimeMapping в .NET просто сопоставляется с расширением, указанным в строке имени файла. Он не проверяет магические байты. –

3

можно легко сделать с помощью ключей реестра.

Dim regKey As Microsoft.Win32.RegistryKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("extension") 
If Not regKey Is Nothing Then 
Dim ct As Object = regKey.GetValue("Content Type") 
    If Not ct Is Nothing Then 
    Return ct.ToString() 
    End If 
End If 

Это даст тот же результат, что и большой список, упомянутый выше !!!!

+1

Это должен быть ответ. –

0

Список This, содержащий 684 дополнительных файлов.

В этом списке каждая пара разделена символом "~", и каждая пара имеет расширение и тип содержимого, разделенные символом "#".

Я не знаю, какой язык вы используете, но это в vb.Чистая

Как использовать:

  1. Добавить строковый ресурс для вас проект, который содержит список. Это будет выглядеть следующим образом - enter image description here
  2. Добавить этот класс в проект (который будет разобрать строку в словарь)

    Public Class MIMETypeList 
        Public data As Dictionary(Of String, String) 
        Public Sub New() 
         data = New Dictionary(Of String, String)() 
         Dim Temp() As String 
         For Each TypeConvertion As String In My.Resources.MimeType.Split("~") 
          Temp = TypeConvertion.Split("#") 
          If Not data.ContainsKey(Temp(0)) Then 
           data.Add(Temp(0), Temp(1)) 
          End If 
         Next 
        End Sub 
    End Class 
    
  3. Теперь вы можете использовать его как это:

    Dim FileExtension1 As String = ".mp4" 
    Dim FileExtension2 As String = ".html" 
    Dim FileExtension3 As String = ".Random" 
    Dim Converter As New MIMETypeList 
    If Converter.data.ContainsKey(FileExtension1) Then 
        Debug.WriteLine(FileExtension1 & " -> " & Converter.data.Item(FileExtension1)) 
    Else 
        Debug.WriteLine(FileExtension1 & " -> File Content Not Found") 
    End If 
    If Converter.data.ContainsKey(FileExtension2) Then 
        Debug.WriteLine(FileExtension2 & " -> " & Converter.data.Item(FileExtension2)) 
    Else 
        Debug.WriteLine(FileExtension2 & " -> File Content Not Found") 
    End If 
    If Converter.data.ContainsKey(FileExtension3) Then 
        Debug.WriteLine(FileExtension3 & " -> " & Converter.data.Item(FileExtension3)) 
    Else 
        Debug.WriteLine(FileExtension3 & " -> File Content Not Found") 
    End If 
    

    Выходные данные:

    .mp4 -> видео/mp4

    .html -> текст/html

    .random -> Файл не найден Содержимое

Смежные вопросы