使用C#编辑二进制文件中的文本

时间:2012-10-18 19:27:26

标签: c#

我有一个二进制文件(即它包含值在0x00和0xFF之间的字节)。我希望使用Regex查找和编辑文件中的ASCII字符串(例如,“Hello World”)。然后,我需要写出已编辑的文件,使其与旧文件完全相同,但我已执行了ASCII编辑。怎么样?

        byte[] inbytes = File.ReadAllBytes(wfile);
        string instring = utf8.GetString(inbytes);
        // use Regex to find/replace some text within instring
        byte[] outbytes = utf8.GetBytes(instring);
        File.WriteAllBytes(outfile, outbytes);

即使我不进行任何编辑,输出文件也不同于输入文件。发生了什么,我怎么能做我想做的事?


编辑:好的,我正在尝试使用提供的建议,并且无法理解如何实际实现它。这是我的示例代码:

        string infile = @"C:\temp\in.dat";
        string outfile = @"C:\temp\out.dat";
        Regex re = new Regex(@"H[a-z]+ W[a-z]+");  // looking for "Hello World"
        byte[] inbytes = File.ReadAllBytes(infile);
        string instring = new SoapHexBinary(inbytes).ToString();
        Match match = re.Match(instring);
        if (match.Success)
        {
            // do work on 'instring'
        }
        File.WriteAllBytes(outfile, SoapHexBinary.Parse(instring).Value);

显然,我知道我不会这样做,但如果我将我的正则表达式转换为字符串(或其他),那么我就不能使用Match等等。任何想法?谢谢!

3 个答案:

答案 0 :(得分:2)

并非所有二进制字符串都是有效的UTF-8字符串。当您尝试将二进制文件解释为UTF-8字符串时,无法解释的字节可能会被破坏。基本上,如果整个文件不是编码文本,那么将其解释为编码文本将不会产生合理的结果。

答案 1 :(得分:1)

使用二进制文件的另一种方法是:将其转换为十六进制字符串,对其进行处理(可在此处使用正则表达式),然后将其保存回来

byte[] buf = File.ReadAllBytes(file);
var str = new SoapHexBinary(buf).ToString();

//str=89504E470D0A1A0A0000000D49484452000000C8000000C808030000009A865EAC00000300504C544......
//Do your work

File.WriteAllBytes(file,SoapHexBinary.Parse(str).Value);

PS:命名空间:System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary

答案 2 :(得分:-1)

我明白了!看看代码:

        string infile = @"C:\temp\in.dat";
        string outfile = @"C:\temp\out.dat";
        Regex re = new Regex(@"H[a-z]+ W[a-z]+");   // looking for "Hello World"
        string repl =  @"Hi there";

        Encoding ascii = Encoding.ASCII;
        byte[] inbytes = File.ReadAllBytes(infile);
        string instr = ascii.GetString(inbytes);
        Match match = re.Match(instr);
        int beg = 0;
        bool replaced = false;
        List<byte> newbytes = new List<byte>();
        while (match.Success)
        {
            replaced = true;
            for (int i = beg; i < match.Index; i++)
                newbytes.Add(inbytes[i]);
            foreach (char c in repl)
                newbytes.Add(Convert.ToByte(c));
            Match nmatch = match.NextMatch();
            int end = (nmatch.Success) ? nmatch.Index : inbytes.Length;
            for (int i = match.Index + match.Length; i < end; i++)
                newbytes.Add(inbytes[i]);
            beg = end;
            match = nmatch;
        }
        if (replaced)
        {
            var newarr = newbytes.ToArray();
            File.WriteAllBytes(outfile, newarr);
        }
        else
        {
            File.WriteAllBytes(outfile, inbytes);
        }