2013-02-10 4 views
6

"テキストファイル"と "バイナリ"ファイルを区別しようとしています。StreamReaderからの元のファイルバイト、マジックナンバーの検出

私にはGZIPアーカイブと思われるファイルがあります。私はマジックナンバー/ファイルのシグネチャを検出することによってこの種のファイルを無視しています。私がメモ帳++で16進エディタプラグインを使ってファイルを開くと、最初の3つの16進コードは1f 8b 08です。

私はStreamReaderを使用してファイルを読み込む場合は、私は、元のバイトを取得するかどうかはわかりません。..

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())); 
} 

私は、次の変数の値を持って使用して文の終わり:

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

どちらもメモ帳++に示されている16進値で始まらない。

StreamReaderでファイルを読み取った結果から元のバイトを取得することはできますか?

+0

を単にバイトのバイトをテスト配列、あなたはすべての文字列stuffを必要としません –

+0

問題は(上の例にもかかわらず)私は実際に私が知っているのはStreamReaderによって生成された文字列で始まり、文字列の供給方法を変更しないことを望んでいました。 [この回答](http://stackoverflow.com/a/10380166/62072)は、文字列から元のバイトを取得することが可能であることを示しているようです..私は何が足りないのですか? –

+0

あなたの16進リーダに表示されている1Fは、49(x31)( '1')と70(x46) 'F' Char(x1f)に変換されます。またはベル。 char(x1f)Char(8B)char(8)を探す必要があるcharsに変換した後にバイトを探しているなら、 –

答えて

5

あなたのコードはバイナリバッファを文字列に変更しようとします。文字列はNETのUnicodeなので、2バイト必要です。あなたが見ることができるように結果は少し予測できません。

だけ(PDFファイルの)BinaryReaderその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

できません。 StreamReaderは、バイナリではなくテキストを読み取るように作られています。直接バイトを読み取るにはStreamを使用してください。あなたのケースではFileStream

ファイルがテキストかバイナリかを推測するには、最初の4Kをbyte[]に読み込んで解釈することができます。

Btw、文字を強制的にバイトにしようとしました。これは原則的に無効です。私はあなたがEncodingが何であるかに慣れさせることをお勧めします:意味的に正しい方法で文字とバイトの間で変換する方法です。

2

使用法を使用:

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

方法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(); 
} 
関連する問題