tags:

views:

89

answers:

3

Could some one help me out in editing a line of a text file(.Hex file) containing all Hex characters without using pointers and in a more efficient way?

It takes so long because the program I have to edit some (around 30x4 bytes or 30 float values from the address values of hex file).

Every time the program replaces one byte, it searches the complete file and replaces the values, and copy back back again the new file to another file. This process repeats 30 times, which is quite time consuming and hence not looks appropriate.

Please help me and suggest an efficient method.

public static string putbyteinhexfile(int address, char data, string total)
{

    int temph, temphl, tempht;
    ushort checksum = 0;
    string output = null, hexa = null;
    StreamReader hex;
    RegistryKey reg = Registry.CurrentUser;
    reg = reg.OpenSubKey("Software\\Calibratortest");
    hex = new StreamReader(((string)reg.GetValue("Select Input Hex File")));
    StreamReader map = new StreamReader((string)reg.GetValue("Select Linker Map File"));
    while ((output = hex.ReadLine()) != null)
    {
        checksum = 0;
        temph = Convert.ToInt16(("0x" + output.Substring(3, 4)), 16);
        temphl = Convert.ToInt16(("0x" + output.Substring(1, 2)), 16);
        tempht = Convert.ToInt16(("0x" + output.Substring(7, 2)), 16);
        if (address >= temph && 
            address < temph + temphl && 
            tempht == 0)
        {
            output = output.Remove((address - temph) * 2 + 9, 2);
            output = output.Insert((address - temph) * 2 + 9, 
                     String.Format("{0:X2}", Convert.ToInt16(data)));

            for (int i = 1; i < (output.Length - 1) / 2; i++)
                checksum += (ushort)Convert.ToUInt16(output.Substring((i * 2) - 1, 2), 16);

            hexa = ((~checksum + 1).ToString("x8")).ToUpper();
            output = output.Remove(temphl * 2 + 9, 2);
            output = output.Insert(temphl * 2 + 9, 
                                   hexa.Substring(hexa.Length - 2, 2));
            break;
        }
        else total = total + output + '\r' + '\n';
    }

    hex.Close();
    map.Close();

    return total;
}
A: 
string fileName = "blabla.hex";
StreamReader f1 = File.OpenText(fileName);
StreamWriter f2 = File.CreateText(fileName + ".temp_");

while (!f1.EndOfStream)
{
    String s = f1.ReadLine();
    //change the content of the variable 's' as you wish 
    f2.WriteLine(s);   
}

f1.Close();
f2.Close();
File.Replace(fileName + ".temp_", fileName, null);
algorian
Not sure how this helps optimize the OP's code so it runs more efficiently...
Kirk Woll
Fellow,The portion while (!f1.EndOfStream) { String s = f1.ReadLine(); //change the content of the variable 's' as you wish f2.WriteLine(s); } is quite same as i implemented, but the thing is , it takes long time in replacing 30 float values in a 78kb hex file.Hex file looks like,:10700000418A57743BC5818E35478AC7AE9D9331FF:10701000C0A5B9B13BF1593FB5E85EC92F103DD2CB:107020003D7B08BDB849C5823251CD69AB8FC16D7A:10703000B9A54DFF3484D605AE8D12CB27C6D349F2:10704000C5181DA23FC677ACB9ADC42532D6AA1467:1070500042A049B2BD1E8A80373E7673B080AB0B2A...
Asad
And if i have to replace a float value(of 4 bytes) in a way such that 2 bytes lie in first line(as its last two bytes) and the other two bytes lie in the second line(as its first two bytes). then I have to be careful in reading and writing because the address for the float value is the same for all 4-bytes,except with a increment of 1 for eacch byte.
Asad
instead of looping over the lines 30 times, each pass replacing 1 float value, why not loop over the lines once, and replace all 30 float values during that single pass? Am I missing something?
James Manning
A: 

Not sure how fast you're going to be able to get this, but one optimization you can take is to use a StringBuilder instead of relying on the methods on class string. By using a StringBuilder you will only be operating against one backing character array, rather than creating new ones all the time on each invocation.

For example:

total = total + output + '\r' + '\n'

Is incredibly inefficient compared to using a StringBuilder:

StringBuilder total = new StringBuilder();
...

else 
{
    total.Append(output);
    total.Append("\r\n");
}
Kirk Woll
`Is incredibly inefficient` is overstating it. The OP is doing huge amount of disk I/O which is thousands of times slower than any speedup he can get by switching to StringBuilder. What the OP really need is to reduce the amount of I/O he's doing.
slebetman
Comparing the performance of ① `var s = total + output + '\r' + '\n';`, ② `var s = total + output + "\r\n";` and ③ `var sb = new StringBuilder(total); sb.Append(output); sb.Append("\r\n"); var result = sb.ToString();`, I notice the performance of ② is by far the fastest. Maybe someone once told you that `StringBuilder` is the ultimate performance panacea, but you should still consider the specific case in which you are giving the advice because it might be an exception.
Timwi
@Timwi, I originally missed the description in the OP's question that he did this 30 times on his file. You are correct that that is the problem. I agree the StringBuilder answer is a micro-optimization -- I didn't realize the calling code was so inefficient. Nobody ever told me that StringBuilder is some sort of "ultimate performance panacea." ;)
Kirk Woll
+3  A: 

Assuming you don't want to massively rewrite your existing logic which does 'for each line, do this search and replace logic', I'd think the simplest change would be:

var lines = File.ReadAllLines(filePath);
foreach (change to make)
{
    for (int i = 0; i < lines.Length; i++)
    {
        // read values from line
        if (need_to_modify)
        {
            // whatever change logic you want here.
            lines[i] = lines[i].Replace(...);
        }
    }
}
File.WriteAllLines(filePath, lines);

Basically, you'll still do the logic you have now, except:

  1. You read the file once instead of N times
  2. you get rid of streamreader / streamwriter work
  3. you do your changes on the array of strings in memory
James Manning
I still don't think this fundamentally addresses the OP's performance problems.
Kirk Woll
@Kirk: The OP's performance problems is precisely due to the large number of reads and writes to disk he's doing. This directly addresses the very fundamentals of the OP's performance problems.
slebetman
Since the OP is not actually writing to disk in his example, I don't see how this can be the case.
Kirk Woll
@Kirk: Read the OP's third paragraph. The given function is called from within a loop (30 times) and the return value of the function is written back to the file before calling the function again (which reopens the file).
slebetman
@slebetman, Thanks for pointing that out. Missed that after he posted the code.
Kirk Woll
@James: Your logic seems much relevant with my coding. I must ry yours one. I hope i be able to get out of my problem .If still i feel any difficulty then i will repost the query. Thanks for all the experts for their valuable comments.
Asad
@James: I have used the same logic as suggested by you, and now i am very pleased to say u thanks for giving me a very nice solution.Now i am not facing any problem of program loading/time consumtion. You are an expert. ThanksThanks for all other for having a healthy technical discussion!!
Asad