This is what i've done so far: [...]
Unfortunately, it's not even close. You haven't even successfully ported
the block-read logic, and that's not the interesting part of sample. It
"handles" cross-block boundaries simply by maintaining enough "previous
data" to account for the length of the search pattern, and then prepending
that to the recently read data before each match attempt. It's also
formatting the bytes as text before doing the match, which is very
inefficient.
Try something like this (warning: uncompiled, untested, unoptimized, no
error-checking, doesn't handle files > 2GB, and assumes that the search
pattern is always no longer than the length of a single block that's
read...proof of concept only):
int FindByteString(string strInputFile, byte[] rgbPattern)
{
byte[] rgbBlockCur = new byte[4096],
rgbBlockNext = new byte[rgbBlockCur.Length];
FileStream stream = File.OpenRead(strInputFile);
int cbBlockCur, cbBlockNext, ibOffset = 0, ibBaseOffset = 0;
cbBlockCur = stream.Read(rgbBlockCur, 0, rgbBlockCur.Length);
cbBlockNext = stream.Read(rgbBlockNext, 0, rgbBlockNext.Length);
while (true)
{
if (ibOffset + rgbPattern.Length <= cbBlockCur)
{
if (FRangesEqual(rgbBlockCur, ibOffset, rgbPattern.Length,
rgbPattern))
{
return ibBaseOffset + ibOffset;
}
}
else if (ibOffset + rgbPattern.Length <= cbBlockCur +
cbBlockNext)
{
if (FRangesEqual(rgbBlockCur, ibOffset, cbBlockCur -
ibOffset, rgbPattern) &&
FRangesEqual(rgbBlockNext, 0, ibOffset +
rgbPattern.Length - cbBlockCur, rgbPattern))
{
return ibBaseOffset + ibOffset;
}
}
else
{
return -1;
}
if (++ibOffset < cbBlockCur.Length)
{
continue;
}
byte[] rgbT = rgbBlockCur;
rgbBlockCur = rgbBlockNext;
rgbBlockNext = rgbT;
ibOffset = 0;
ibBaseOffset += cbBlockCur;
cbBlockCur = cbBlockNext;
cbBlockNext = stream.Read(rgbBlockNext, 0,
rgbBlockNext.Length);
}
}
bool FRangesEqual(byte[] rgb, int ibStart, int ibLength, byte[]
rgbPattern)
{
for (int ibPattern = 0; ibPattern < ibLength; ibPattern++)
{
if (rgb[ibStart + ibPattern] != rgbPattern[ibPattern])
{
return false;
}
}
return true;
}
There are a number of refinements one might make to the above. But even
that basic example ought to perform much better than a C# port of the
PowerShell script you posted. I apologize in advance for any typos or
bugs; hopefully it's enough to get you pointed in the right direction, in
spite of any flaws that might be present.
Pete