2016-04-15 6 views
-1

私はC#で新しいです、私はファイル内のバイトパターンをカウントしたいと思います。私は小さなファイル(8MB)を読み込もうとしても結果は1907になりますが、大きなファイル(50MB)を読み込もうとするとアプリはフリーズして何も返しません。これはこれまでの私のコードです。C#大きなファイルのバイトパターンを読み取る

public long chunkMethodCW() 
{ 
    int incomingOffset = 0; 
    byte[] outboundBuffer = new byte[1024]; 
    long CW = 0; 
    KMP kmp = new KMP(header); // header = pattern in hex 

    while(incomingOffset < data.Length) 
    { 
     int length = Math.Min(outboundBuffer.Length,data.Length - incomingOffset); 

     Buffer.BlockCopy(data,incomingOffset,outboundBuffer,0,length); 
     incomingOffset += length; 

     //CW += kmp.match(outboundBuffer); 
     CW++; 
    } 

    return CW; 
} 

// KMP Class 
public class KMP 
{ 
    private int[] F; 
    private byte[] pat; 
    private int m; 

    public KMP(byte[] pattern) 
    { 
     pat = pattern; 
     m = pattern.Length; 
     F = new int[m + 1]; 

     for (int i = 2, j; i <= m; i++) 
     { 
      j = F[i - 1]; 

      if (pattern[j] == pattern[i - 1]) 
      { 
       F[i] = j + i; 
       continue; 
      } 

      while(j > 0 && pat[j] != pat[i-1]) 
      { 
       j = F[j]; 
      } 

      F[i] = pat[j] != pat[i - 1] ? 0 : j + 1; 
     } 
    } 

    public int match(byte[] data) 
    { 
     int n = data.Length, pi = 0, ti = 0; 
     int matches = 0; 

     while (ti < n) 
     { 
      if (pi == m) 
      { 
       matches++; 
       pi = 0; 
       pi = F[pi]; 
      } 

      if (data[ti] == pat[pi]) 
      { 
       pi++; 
       ti++; 
      } 

      else if (pi > 0) 
      { 
       pi = F[pi]; 
      } 
      else 
      { 
       ti++; 
      } 
     } 

     if (pi == m) 
     { 
      matches++; 
      pi = 0; 
      pi = F[pi]; 
     } 

     return matches; 
    } 
} 

私はまだ自分のコードをテストしていて、今、私は私のコードは、その開始時にパターンを満たしていない時に凍結が起こっている、または開始とするときのパターンを満たすとの間に大きなギャップがあることを実現します。私のコードを改善して、開始パターンと最初に一致するパターンの間に大きなギャップがあるときにフリーズしないようにするための提案はありますか?ありがとうございます

+0

このコードの壁にはどんなことが期待されますか? –

+0

大きなファイルをスムーズに処理できるように、自分のコードや提案を改善したり、完全に変更したりすることに問題がありますか?ありがとうございます –

+0

提案:あなたの変数を命名するときに5文字以上を使用してください。あなたのコードをより読みやすくします – chrisl08

答えて

0

ソースとパターンのバイト配列の長さは?私は試してみましたが、それは私に63MBのファイルでフリーズを与えませんでした。

Oh btw実装に「バグ」があります。 1024バイト長の「ウィンドウ」のようなものを使用することになっていますか?基本的にバイトはウィンドウにコピーされ、KMPはパターンの一致をウィンドウに適用し、ウィンドウは次のバイトを読み込むまでスライドします。カットオフがパターンの中央にある場合、パターンマッチの正しい数が返されません。私は以下のコードを修正しましたので、毎回ウィンドウをスライドさせないようにしました(0120)。

public static long SearchBytePattern(byte[] source, byte[] patternToFind) 
{ 
    int incomingOffset = 0; 
    byte[] window = new byte[1024]; 
    long count = 0; 
    KMP kmp = new KMP(patternToFind); 

    while (incomingOffset < source.Length) 
    { 
     int length = Math.Min(window.Length, source.Length - incomingOffset); 

     Buffer.BlockCopy(source, incomingOffset, window, 0, length); 
     incomingOffset += length; 

     count += kmp.match(window); 

     if (incomingOffset >= source.Length) 
      break; 
     else 
      incomingOffset -= patternToFind.Length - 1; 
    } 

    return count; 
}