3

我有一个二进制文件(即,它包含值在 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);

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

4

3 回答 3

2

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

于 2012-10-18T20:04:34.213 回答
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

于 2012-10-18T20:12:27.427 回答
-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);
        }
于 2012-10-22T16:52:41.873 回答