如何在C#中实现字节模式检测、CheckedListBox展示及bin文件替换保存?
完整解决方案
1. 定义DTC数据结构
先创建一个类封装每个DTC的核心信息,方便管理上百种模式:
public class DtcInfo { // 字节模式(十六进制字符串) public string HexPattern { get; set; } // DTC名称(如P0420) public string Name { get; set; } // DTC描述 public string Description { get; set; } // 存储该模式在文件中的所有偏移位置 public List<int> Offsets { get; set; } = new List<int>(); }
2. 初始化DTC配置
把所有字节模式按上述结构配置,示例如下:
private List<DtcInfo> _dtcList = new List<DtcInfo> { new DtcInfo { HexPattern = "2004940101000078", Name = "P0420", Description = "Catalyst System Efficiency Below Threshold Bank1" }, new DtcInfo { HexPattern = "3004940101000078", Name = "P0430", Description = "Catalyst System Efficiency Below Threshold Bank2" }, new DtcInfo { HexPattern = "3E04940101000028", Name = "P043E", Description = "EvaporativeEmissionSystemLeakDetectionReferenceOrificeLowFlow" } };
3. 打开BIN文件并转为byte数组
通过OpenFileDialog选择文件,直接读取为byte数组:
private byte[] OpenBinFile() { using (OpenFileDialog openFileDialog = new OpenFileDialog()) { openFileDialog.Filter = "BIN文件 (*.bin)|*.bin|所有文件 (*.*)|*.*"; openFileDialog.RestoreDirectory = true; if (openFileDialog.ShowDialog() == DialogResult.OK) { return File.ReadAllBytes(openFileDialog.FileName); } } return null; }
4. 高效字节模式搜索工具
直接在byte数组中搜索,避免字符串转换的性能损耗,支持查找所有匹配位置:
// 查找模式在源数组中的所有偏移位置 private List<int> FindAllOccurrences(byte[] source, byte[] pattern) { List<int> offsets = new List<int>(); int patternLength = pattern.Length; int sourceLength = source.Length; if (patternLength == 0 || sourceLength < patternLength) return offsets; for (int i = 0; i <= sourceLength - patternLength; i++) { bool match = true; for (int j = 0; j < patternLength; j++) { if (source[i + j] != pattern[j]) { match = false; break; } } if (match) { offsets.Add(i); } } return offsets; } // 辅助方法:十六进制字符串转byte数组 private byte[] HexStringToByteArray(string hex) { int length = hex.Length; byte[] bytes = new byte[length / 2]; for (int i = 0; i < length; i += 2) { bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); } return bytes; }
5. 搜索并填充CheckedListBox
执行搜索逻辑,将找到的DTC项加载到CheckedListBox中:
private byte[] _currentFileBytes; // 存储当前打开的文件字节数组 private void SearchAndLoadDtc() { _currentFileBytes = OpenBinFile(); if (_currentFileBytes == null) return; checkedListBox1.Items.Clear(); foreach (var dtc in _dtcList) { byte[] patternBytes = HexStringToByteArray(dtc.HexPattern); dtc.Offsets = FindAllOccurrences(_currentFileBytes, patternBytes); // 找到匹配项则添加到列表,同时关联DtcInfo对象 if (dtc.Offsets.Count > 0) { checkedListBox1.Items.Add($"{dtc.Name} - {dtc.Description}", false); checkedListBox1.Items[checkedListBox1.Items.Count - 1].Tag = dtc; } } }
6. 替换选中项并保存新文件
处理勾选后的替换逻辑,生成并保存修改后的BIN文件:
private void SaveModifiedBinFile() { if (_currentFileBytes == null || checkedListBox1.CheckedItems.Count == 0) return; // 复制原数组,避免修改原始文件 byte[] modifiedBytes = (byte[])_currentFileBytes.Clone(); foreach (var item in checkedListBox1.CheckedItems) { var dtc = item.Tag as DtcInfo; if (dtc == null) continue; // 生成与模式长度一致的空字节数组 byte[] replacementBytes = new byte[dtc.HexPattern.Length / 2]; // 替换所有匹配位置的字节 foreach (int offset in dtc.Offsets) { Array.Copy(replacementBytes, 0, modifiedBytes, offset, replacementBytes.Length); } } // 保存修改后的文件 using (SaveFileDialog saveFileDialog = new SaveFileDialog()) { saveFileDialog.Filter = "BIN文件 (*.bin)|*.bin|所有文件 (*.*)|*.*"; saveFileDialog.RestoreDirectory = true; saveFileDialog.FileName = "modified_" + Path.GetFileNameWithoutExtension(openFileDialog.FileName) + ".bin"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { File.WriteAllBytes(saveFileDialog.FileName, modifiedBytes); MessageBox.Show("文件保存成功!"); } } }
7. 界面按钮绑定
在WinForm设计器中添加两个按钮(btnOpenSearch、btnSave),绑定点击事件:
private void btnOpenSearch_Click(object sender, EventArgs e) { SearchAndLoadDtc(); } private void btnSave_Click(object sender, EventArgs e) { SaveModifiedBinFile(); }
关键改进说明
- 性能优化:直接操作byte数组搜索,避免大文件转字符串的内存与性能损耗
- 可扩展性:新增模式只需在
_dtcList中添加对象,无需修改核心逻辑 - 完整性:支持查找所有匹配位置,并批量替换所有出现的目标模式
- 安全性:修改时操作原数组副本,避免破坏原始文件
内容的提问来源于stack exchange,提问作者Malik
相关产品推荐
相关产品推荐

