2016-10-18 4 views
0

Я разрешаю пользователям загружать определенные файлы на мой сервер, и я хотел бы подтвердить, что они не изменили расширение файла. Например, пользователь может переименовать файл .bat в .xlsx, а затем загрузить его.Признать фактический тип загружаемого файла?

Я пытаюсь обнаружить истинный тип файла. Для документов Office (.docx и т. Д.) Я могу открыть файл в виде ZIP-файла и найти известный каталог (word/ для .docx, xl/ для .xlsx и т. Д.).

Я использую следующий код:

private static FileType CheckForCompressFile(FileType type, string fileFullName) 
{ 
    FileType result = null; 
    using (var zipFile = ZipFile.OpenRead(fileFullName)) 
    { 
     if (zipFile.Entries.Any(e => e.FullName.StartsWith("word/"))) 
      result = WORDX; 
     else if (zipFile.Entries.Any(e => e.FullName.StartsWith("xl/"))) 
      result = EXCELX; 
     else if (zipFile.Entries.Any(e => e.FullName.StartsWith("ppt/"))) 
      result = PPTX; 
     else if (zipFile.Entries.Any(e => e.FullName.StartsWith("sbt/"))) 
      result = JAR; 
     else 
      result = CheckForOdtAndOds(result, zipFile); 
    } 
    return result; 
    } 

Но ZIP поддержка в System.IO доступна только в .NET 4.5, и мне нужно использовать .NET 4.0. Какие у меня варианты?

+0

Там же два вопроса. И что вы подразумеваете под * файловой базой *? – Lloyd

+0

Что значит «расширение файловой базы»? Вы хотите выяснить, что у вас действительно есть файл Excel, а не файл Word? –

+0

@ LasseV.Karlsen: Из этого кода я бы сказал «да». –

ответ

0

Я думаю, что вы пытаетесь сделать это непросто, извините. В предыдущих версиях Office вы могли бы разделить тип файла, прочитав первые байты файла и проверив там подпись. Но в новых форматах xlsx, docx ... все они имеют одну и ту же подпись, потому что они являются сжатыми файлами, поэтому все они начинаются с «PK ..». Вы можете проверить, что я говорю так:

byte[] fileBytes = File.ReadAllBytes(@"file.docx"); 
string signature = ((char)fileBytes[0]).ToString() + ((char)fileBytes[1]).ToString(); 
Console.WriteLine(signature); 

Это пишет «PK», независимо от того, если его слова, Excel, PowerPoint файл ...

Here у вас есть список различных типов файлов подписи. Там вы увидите, что все офисные документы одинаковы.

Редактировать

Хорошо, теперь я понимаю, что вы делаете. Вы хотите распаковать офисные файлы, чтобы указать тип файла отдельно. Вы можете сделать это следующим образом:

private static FileType CheckForCompressFile(FileType type, string fileFullName) 
{ 
    FileType result = null; 
    FileStream fileBytes = new FileStream(fileFullName, FileMode.Open); 
     using (System.IO.Compression.ZipArchive zipFile = new System.IO.Compression.ZipArchive(fileBytes)) 
     { 
      if (zipFile.Entries.Any(e => e.FullName.StartsWith("word/"))) 
       result = WORDX; 
      else if (zipFile.Entries.Any(e => e.FullName.StartsWith("xl/"))) 
       result = EXCELX; 
      else if (zipFile.Entries.Any(e => e.FullName.StartsWith("ppt/"))) 
       result = PPTX; 
      else if (zipFile.Entries.Any(e => e.FullName.StartsWith("sbt/"))) 
       result = JAR; 
      else 
       result = CheckForOdtAndOds(result, zipFile); 
     } 
     return result; 
    } 

Вы должны добавить ссылку на Compression namespace, если вы хотите использовать его в Net 4.0. Я также советую вам использовать мое предыдущее решение подписи, чтобы решить, является ли файл сжатым файлом перед вызовом этого метода.

Edit 2

Если вам это нужно для Net4.0, я советую вам использовать бесплатную библиотеку Zip, а DotNetZip. Он прост в использовании. Просто скачайте ZIP по ссылке, распакуйте файл Ionic.Zip.dll из папки zip-v1.9\Release, добавьте ссылку на этот файл в вашей proyect, а затем просто сделать это:

private static FileType CheckForCompressFile(string fileFullName) 
{ 
    FileType result = null; 

    using (Ionic.Zip.ZipFile zipFile = new Ionic.Zip.ZipFile(fileFullName)) 
    { 
     if (zipFile.Entries.Any(e => e.FileName.StartsWith("word/"))) 
      result = WORDX; 
     else if (zipFile.Entries.Any(e => e.FileName.StartsWith("xl/"))) 
      result = EXCELX; 
     else if (zipFile.Entries.Any(e => e.FileName.StartsWith("ppt/"))) 
      result = PPTX; 
     else if (zipFile.Entries.Any(e => e.FileName.StartsWith("sbt/"))) 
      result = JAR; 
     else 
      result = CheckForOdtAndOds(result, zipFile); 
    } 
    return result; 
} 
+0

Спасибо за вашу поддержку. Я пытаюсь, но не работаю: «не могу разрешить символ« ZipArchive ». Net 4.0 не поддерживает zipfile и ziparchive –

+0

Добавили ли вы ссылку на' System.IO.Compression' в своем проекте? – Pikoh

+0

@ngocchaunguyen Я ошибался, 'System .IO.Compression' недоступно в Net 4.0. Посмотрите мое второе редактирование для альтернативы. Я пробовал, и все работает отлично. Надеюсь, это поможет – Pikoh

0

Взгляните на пространство имен System.IO.Packaging, которое содержит поддержку ZIP-файлов, но не все возможности ZIP-файлов.

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