2016-03-13 2 views
2

im пытается выяснить, не является ли файл без расширения изображением, но, похоже, он прав. Я знаю его определенно образ, потому что я могу открыть его в маске ms. Вот мой код все равноОбнаруживать, если файл без расширения - это изображение

 private bool IsImage(Stream stream) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 

     List<string> jpg = new List<string> { "FF", "D8" }; 
     List<string> bmp = new List<string> { "42", "4D" }; 
     List<string> gif = new List<string> { "47", "49", "46" }; 
     List<string> png = new List<string> { "89", "50", "4E", "47", "0D", "0A", "1A", "0A" }; 
     List<List<string>> imgTypes = new List<List<string>> { jpg, bmp, gif, png }; 

     List<string> bytesIterated = new List<string>(); 

     for (int i = 0; i < 8; i++) 
     { 
      string bit = stream.ReadByte().ToString("X2"); 
      bytesIterated.Add(bit); 

      bool isImage = imgTypes.Any(img => !img.Except(bytesIterated).Any()); 
      if (isImage) 
      { 
       textBox1.Text = "is image"; 
       return true; 
      } 
     } 
     textBox1.Text = "is not image"; 
     return false; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     string filepath = @"C:\Users\William\Documents\drivers\2"; 
     MemoryStream mStrm = new MemoryStream(Encoding.UTF8.GetBytes(filepath)); 
     IsImage(mStrm); 
    } 

также игнорируют, что его в файле с именем драйвера, файл не является драйвером или что-нибудь

+0

здесь: http://stackoverflow.com/questions/9354747/how-can-i-determine-if-a-file-is-an-image-file-in-net –

+0

Это выглядит многообещающим, больным посмотрите, спасибо – Will

+0

Какое сообщение об ошибке вы получаете? – Coding4Fun

ответ

2

Если вы пытаетесь сравнить последовательности байтов в заголовке, лучше сравнить byte[], чем string s.

// simple class to associate a signature with a name 
public class ImgHeader 
{ 
    public readonly string Name; 
    public readonly byte[] Header; 

    public static readonly ImgHeader GIF89a = new ImgHeader("GIF89a", new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }); 
    public static readonly ImgHeader GIF87a = new ImgHeader("GIF87a", new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }); 
    public static readonly ImgHeader JPG = new ImgHeader("JPG", new byte[]{0xFF, 0xD8}); 
    public static readonly ImgHeader PNG = new ImgHeader("PNG", new byte[] {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }); 

    private ImgHeader(string n, byte[] h) 
    { 
     this.Name = n; 
     this.Header = h; 
    } 
} 

Затем коллекция из них (обратите внимание, что список может быть больше BMP, TIFF и т.д.):

List<ImgHeader> imgSigs = new List<ImgHeader>(); 

imgSigs.Add(ImgHeader.GIF87a); 
imgSigs.Add(ImgHeader.GIF89a); 
imgSigs.Add(ImgHeader.JPG); 
imgSigs.Add(ImgHeader.PNG); 

Учитывая List<string>, представляющий полное имя файла, перебирать и сравнивать байты заголовка:

foreach (string s in files) 
{ 
    using (FileStream fs = new FileStream(s,FileMode.Open, FileAccess.Read)) 
    using (BinaryReader br = new BinaryReader(fs)) 
    { 
     //max header size 
     byte[] hdr = br.ReadBytes(8); 

     foreach (ImgHeader sig in imgSigs) 
     { 
      // subset of bytes read for comparison 
      byte[] testHdr = new byte[sig.Header.Length]; 
      Array.Copy(hdr, testHdr, sig.Header.Length); 

      //if(CompareBytes(hdr, sig.Header)) 
      if (testHdr.SequenceEqual(sig.Header)) 
      { 
       Console.WriteLine("{0} is {1}", s, sig.Name); 
       break; 
      } 
     } 
    } 
} 

Вместо того, чтобы создать массив временного и копирование использовать SequenceEqual это может быть быстрее вызвать метод компаратора, который использует for n, чтобы тестировать столько байтов, сколько указано в заданном массиве сигнатур.


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

0

использование FileStream вместо MemoryStream так:

private void button1_Click(object sender, EventArgs e) 
    { 
     string filepath = @"C:\Users\William\Documents\drivers\2"; 
     var mStrm = new FileStream(filepath , FileMode.Open, FileAccess.Read) 
     IsImage(mStrm); 
    } 

Надежда это help