views:

127

answers:

1

I have a binary file, where are a few values what should be changed. To be more exact, at two part of the file, in the beginning, there are two HEX values

66 73 69 6D 35 2E 36 39

what should be changed to

4D 53 57 49 4E 34 2E 31

How could I do this async, and as fast as possible? I've got to the point where I read the whole file into a byte[] array, but this class has no search or replace feature.

+1  A: 

Here is a method I wrote which you can use to find where in your byte[] the bytes are that you are trying to find.

/// <summary>
/// Searches the current array for a specified subarray and returns the index
/// of the first occurrence, or -1 if not found.
/// </summary>
/// <param name="sourceArray">Array in which to search for the
/// subarray.</param>
/// <param name="findWhat">Subarray to search for.</param>
/// <param name="startIndex">Index in <paramref name="sourceArray"/> at which
/// to start searching.</param>
/// <param name="sourceLength">Maximum length of the source array to search.
/// The greatest index that can be returned is this minus the length of
/// <paramref name="findWhat"/>.</param>
public static int IndexOfSubarray<T>(this T[] sourceArray, T[] findWhat,
        int startIndex, int sourceLength) where T : IEquatable<T>
{
    if (sourceArray == null)
        throw new ArgumentNullException("sourceArray");
    if (findWhat == null)
        throw new ArgumentNullException("findWhat");
    if (startIndex < 0 || startIndex > sourceArray.Length)
        throw new ArgumentOutOfRangeException();
    var maxIndex = sourceLength - findWhat.Length;
    for (int i = startIndex; i <= maxIndex; i++)
    {
        if (sourceArray.SubarrayEquals(i, findWhat, 0, findWhat.Length))
            return i;
    }
    return -1;
}

/// <summary>Determines whether the two arrays contain the same content in the
/// specified location.</summary>
public static bool SubarrayEquals<T>(this T[] sourceArray,
        int sourceStartIndex, T[] otherArray, int otherStartIndex, int length)
        where T : IEquatable<T>
{
    if (sourceArray == null)
        throw new ArgumentNullException("sourceArray");
    if (otherArray == null)
        throw new ArgumentNullException("otherArray");
    if (sourceStartIndex < 0 || length < 0 || otherStartIndex < 0 ||
        sourceStartIndex + length > sourceArray.Length ||
        otherStartIndex + length > otherArray.Length)
        throw new ArgumentOutOfRangeException();

    for (int i = 0; i < length; i++)
    {
        if (!sourceArray[sourceStartIndex + i]
            .Equals(otherArray[otherStartIndex + i]))
            return false;
    }
    return true;
}
Timwi
Thank you very much, will try it ASAP!
fonix232
Sadly not working, even if I create a new class for it, it won't find the SubarrayEquals functions :S
fonix232
@fonix232: It’s in my code. Are you sure you copied all of it?
Timwi
Yea, I'm sure, copied it into my code (don't know if it matters, but it's a Win Console app, copied functions to Main()) and at if (sourceArray.SubarrayEquals(i, findWhat, 0, findWhat.Length))it tells me Array has no such function "SubarrayEquals".
fonix232
@fonix232: The methods are extension methods. You have to put them into a *public static class*. Sorry I didn’t mention that. Alternatively, you can just change the call to `if (SubarrayEquals(sourceArray, i, findWhat, 0, findWhat.Length))`.
Timwi
@fonix232: You're probably using C# 2.0 , which don't support Extension Methods.
Claus Jørgensen
@Claus: Surely then he would get an error pointing to the “this” keyword instead of the call.
Timwi
Nope, I am using C# 4.0! But finally solved by the second method you mentioned Timwi, thank you very much! It is working now, now I get the index of the stuff :D
fonix232