C# Binary File Replacement

J

Jeffrey D. Gordon

I'm wanting to replace Field Values in an existing PDF, I've done this
with PHP by doing a replace in the file.

I've been able to read the file in a byte array in c# but all my
attempts to replace strings in a binary file have led to failure for the
last couple of days.

I've stared at this function for too long I've become crosseyed ;)

Any suggestions, or is there an easier way to replace in a byte array og
which I'm not aware?


With thanks,
JDG

------------------ BEGIN CODE -------------------
private byte[] ReplaceInByteArray(byte[] OriginalArray, byte[] Find,
byte[] Replace)
{
byte[] ReturnValue = OriginalArray;

if(System.Array.BinarySearch(ReturnValue, Find) > -1 )
{
byte[] NewReturnValue;
int lFoundPosition;
int lCurrentPosition;
while(System.Array.IndexOf(ReturnValue, Find) > -1 )
{
NewReturnValue = new byte[ReturnValue.Length + Find.Length -
Replace.Length];
lFoundPosition = System.Array.IndexOf(ReturnValue, Find);
lCurrentPosition = 0;

for(int x = 0; x < lFoundPosition; x++)
{
NewReturnValue[x] = ReturnValue[x];
lCurrentPosition++;
}

for(int y = 0; y < Replace.Length; y++)
{
NewReturnValue[y + lCurrentPosition] = Replace[y];
}

lCurrentPosition = lCurrentPosition + Replace.Length;

while(lCurrentPosition < NewReturnValue.Length)
{
NewReturnValue[lCurrentPosition] = ReturnValue[lCurrentPosition -
Replace.Length + Find.Length];
lCurrentPosition++;
}

ReturnValue = NewReturnValue;
}


}

return ReturnValue;
}
------------------ END CODE -------------------
 
J

Justin Rogers

No reason to return a new array. You can use the FileStream class to read a
single byte
at a time (it caches internally for optimum disk read buffer performance), match
it against
your find array, and then then set your position back to the beginning to easily
write out
your replacement array.

The issue would be if your replacement is longer than your find array. If this
is the case
some different methods would have to be used in order to *make room* for the
replacement.
Doing an inline file search and replace would definitely yield the fastest and
probably one of
the easiest algorithms.

Your own algorithm is truly flawed in that BinarySearch does not search for an
array of elements
within an array, but instead a single element. And it only does so correctly if
the array is sorted.
 
J

Jeffrey D. Gordon

These are the two functions I wrote to make this work for me.

Thanks to Justin Rogers for showing me the light in how Binary Search
works, after sleeping on it I decided to write my own byte array search
function.
----------------------- BEGIN CODE -------------------------------
private byte[] ReplaceInByteArray(byte[] OriginalArray, byte[] Find,
byte[] Replace)
{
byte[] ReturnValue = OriginalArray;

if(System.Array.BinarySearch(ReturnValue, Find) > -1 )
{
byte[] NewReturnValue;
int lFoundPosition;
int lCurrentPosition;
int lCurrentOriginalPosition;
while(FindInByteArray(ReturnValue, Find) > -1 )
{
NewReturnValue = new byte[ReturnValue.Length + Replace.Length -
Find.Length];
lFoundPosition = FindInByteArray(ReturnValue, Find);
lCurrentPosition = 0;
lCurrentOriginalPosition = 0;

for(int x = 0; x < lFoundPosition; x++)
{
NewReturnValue[x] = ReturnValue[x];
lCurrentPosition++;
lCurrentOriginalPosition++;
}

for(int y = 0; y < Replace.Length; y++)
{
NewReturnValue[lCurrentPosition] = Replace[y];
lCurrentPosition++;
}

lCurrentOriginalPosition = lCurrentOriginalPosition + Find.Length;

while(lCurrentPosition < NewReturnValue.Length)
{
NewReturnValue[lCurrentPosition] =
ReturnValue[lCurrentOriginalPosition];
lCurrentPosition++;
lCurrentOriginalPosition++;
}

ReturnValue = NewReturnValue;
}

}
return ReturnValue;
}

private int FindInByteArray(byte[] Haystack, byte[] Needle)
{
int lFoundPosition = -1;
int lMayHaveFoundIt = -1;
int lMiniCounter = 0;

for(int lCounter = 0; lCounter < Haystack.Length; lCounter++)
{
if(Haystack[lCounter] == Needle[lMiniCounter])
{
if(lMiniCounter == 0)
lMayHaveFoundIt = lCounter;
if(lMiniCounter == Needle.Length - 1)
{
return lMayHaveFoundIt;
}
lMiniCounter++;
}
else
{
lMayHaveFoundIt = -1;
lMiniCounter = 0;
}
}

return lFoundPosition;
}
------------------------- END CODE -------------------------------
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top