2013-02-10 21 views
6

Tôi đang cố gắng phân biệt giữa tệp "tệp văn bản" và "nhị phân", vì tôi thực sự muốn bỏ qua các tệp có nội dung "không đọc được".byte tệp gốc từ StreamReader, phát hiện số ảo

Tôi có một tệp mà tôi tin là một kho lưu trữ GZIP. Tôi đang tring để bỏ qua các loại tập tin bằng cách phát hiện các chữ số ma thuật/chữ ký tập tin. Nếu tôi mở tệp bằng trình chỉnh sửa Hex plugin trong Notepad ++, tôi có thể thấy ba mã hex đầu tiên là 1f 8b 08.

Tuy nhiên, nếu tôi đọc các tập tin bằng cách sử dụng StreamReader, tôi không chắc chắn làm thế nào để có được các byte gốc ..

using (var streamReader = new StreamReader(@"C:\file")) 
{ 
    char[] buffer = new char[10]; 
    streamReader.Read(buffer, 0, 10); 
    var s = new String(buffer); 

    byte[] bytes = new byte[6]; 
    System.Buffer.BlockCopy(s.ToCharArray(), 0, bytes, 0, 6); 
    var hex = BitConverter.ToString(bytes); 

    var otherhex = BitConverter.ToString(System.Text.Encoding.UTF8.GetBytes(s.ToCharArray())); 
} 

Vào cuối báo cáo kết quả sử dụng Tôi có giá trị biến sau:

hex: "1F-00-FD-FF-08-00" 
otherhex: "1F-EF-BF-BD-08-00-EF-BF-BD-EF-BF-BD-0A-51-02-03" 

Không bắt đầu bằng giá trị hex nào trong Notepad ++.

Có thể nhận các byte gốc từ kết quả đọc tệp qua StreamReader không?

+0

chỉ kiểm tra các byte trong byte mảng, bạn không cần tất cả các công cụ chuỗi –

+0

Vấn đề là (mặc dù ví dụ trên) Tôi thực sự ly bắt đầu với một chuỗi (mà tôi biết được sản xuất bởi một StreamReader) và tôi đã hy vọng không phải thay đổi cách chuỗi được cung cấp. [Câu trả lời này] (http://stackoverflow.com/a/10380166/62072) dường như chỉ ra rằng nó có thể nhận được các byte gốc từ một chuỗi .. Tôi đang thiếu gì? –

+0

1F mà bạn thấy trong trình đọc hex của bạn là 31 được chuyển đổi thành 49 (x31) ('1') và 70 (x46) 'F' Char (x1f) là ascii char của Hoa Kỳ (dấu tách đơn vị) không thể in như esc hoặc chuông. vì vậy nếu bạn đang tìm kiếm các byte sau khi có hiệu quả chuyển đổi sang ký tự you'ev đã tìm Char (x1f) Char (8B) char (8) –

Trả lời

5

Mã của bạn cố gắng thay đổi bộ đệm nhị phân thành chuỗi. Các chuỗi là Unicode trong NET do đó yêu cầu hai byte. Kết quả là một chút không thể đoán trước như bạn có thể thấy.

Chỉ cần sử dụng một BinaryReader và phương pháp ReadBytes

using(FileStream fs = new FileStream(@"C:\file", FileMode.Open, FileAccess.Read)) 
{ 
    using (var reader = new BinaryReader(fs, new ASCIIEncoding())) 
    { 
     byte[] buffer = new byte[10]; 
     buffer = reader.ReadBytes(10); 
     if(buffer[0] == 31 && buffer[1] == 139 && buffer[2] == 8) 
      // you have a signature match.... 
    } 
} 
2

Bạn không thể. StreamReader được thực hiện để đọc văn bản, không phải nhị phân. Sử dụng trực tiếp số Stream để đọc byte. Trong trường hợp của bạn FileStream.

Để đoán xem tệp có phải là văn bản hay nhị phân, bạn có thể đọc 4K đầu tiên thành byte[] và diễn giải điều đó.

Btw, bạn đã cố gắng buộc ký tự thành byte. Điều này là không hợp lệ theo nguyên tắc. Tôi khuyên bạn nên tự làm quen với những gì mà Encoding là: nó là chỉ cách để chuyển đổi giữa các ký tự và byte theo cách ngữ nghĩa chính xác.

2

sử dụng (cho một tập tin pdf):

Assert.AreEqual("25504446", GetMagicNumbers(filePath, 4)); 

Phương pháp GetMagicNumbers:

private static string GetMagicNumbers(string filepath, int bytesCount) 
{ 
    // https://en.wikipedia.org/wiki/List_of_file_signatures 

    byte[] buffer; 
    using (var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read)) 
    using (var reader = new BinaryReader(fs)) 
     buffer = reader.ReadBytes(bytesCount); 

    var hex = BitConverter.ToString(buffer); 
    return hex.Replace("-", String.Empty).ToLower(); 
} 
Các vấn đề liên quan