using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace S19File { class S19FileStream { public List FileText; //数据大小 private int size; public int Size { get { return size; } } //起始地址 private int startAddr; public int StartAddr { get { return startAddr; } } //结束地址 private int endAddr; public int EndAddr { get { return endAddr; } } public S19FileStream() { FileText = new List(); size = 0; startAddr = 0; endAddr = 0; } public S19FileStream(string FileName) { StreamReader StreamRead = new StreamReader(FileName, System.Text.Encoding.Default); FileText = new List(); string LineText; while ((LineText = StreamRead.ReadLine()) != null) { if (0 != LineText.Length) { FileText.Add(LineText); } } size = GetSize(); startAddr = GetStartAddr(); endAddr = GetEndAddr(); } //清除读取到的S19数据 public void Clear() { this.FileText.Clear(); size = 0; startAddr = 0; endAddr = 0; } //获取S19文件的数据的大小 private int GetSize() { int size; int startAddr; int endAddr; int endLineNum; int endLineDataLen; //获取起始地址 startAddr = this.GetStartAddr(); endAddr = this.GetEndAddr(); endLineNum = this.GetEndLineNum(); endLineDataLen = this.GetLineDataLen(endLineNum); size = endAddr - startAddr + endLineDataLen; return size; } //一字节转16进制字符串 小于0x10往前补零 private string ByteToStringHex(byte num) { string str; if (num >= 0x10) { str = Convert.ToString(num, 16); } else { str = "0" + Convert.ToString(num, 16); } return str.ToUpper(); } public byte[] ToBinByteArray(int size) { string s19Head; int count = 0; int lineAddrLen; int lineDataLen; List dataBuff = new List(); foreach (string line in this.FileText) { s19Head = line.Substring(0, 2); lineDataLen = Convert.ToByte(line.Substring(2, 2), 16); /*lineAddrLen = s19Head switch { "S1" => 4, "S1" }*/ switch (s19Head) { case "S1": { lineAddrLen = 4; break; } case "S2": { lineAddrLen = 6; break; } case "S3": { lineAddrLen = 8; break; } default: lineAddrLen = 0; break; } if (0 != lineAddrLen) { for (int i = lineAddrLen + 4; i < (lineDataLen << 1) + 2; i += 2) { dataBuff.Add(Convert.ToByte(line.Substring(i, 2), 16)); count++; if (count >= size) { return dataBuff.ToArray(); } } } } return dataBuff.ToArray(); } //获取S19行存放地址的长度 private int GetLineAddrLen(int line) { string s19LineHead; int lineAddrLen; if ((line < this.FileText.Count) && (line >= 0) ) { s19LineHead = this.FileText[line].Substring(0, 2); } else { s19LineHead = ""; } switch (s19LineHead) { case "S1": { lineAddrLen = 4; break; } case "S2": { lineAddrLen = 6; break; } case "S3": { lineAddrLen = 8; break; } default: lineAddrLen = 0; break; } return lineAddrLen; } private int GetLineAddr(int line) { //一行的头 S0 S1 S2 S3 ... //string s19LineHead; //要读取的行的地址数据的长度 int lineAddrLen; //要读取的行的地址 int lineAddr; lineAddrLen = GetLineAddrLen(line); if (0 == lineAddrLen) { lineAddr = 0; } else { lineAddr = Convert.ToInt32(this.FileText[line].Substring(4, lineAddrLen), 16); } return lineAddr; } private int GetStartAddr() { string s19Head; //int lineAddrLen; int startAddr; int headLineNum = 0; s19Head = this.FileText[0].Substring(0, 2); if ("S0" == s19Head) { headLineNum = 1; } startAddr = GetLineAddr(headLineNum); return startAddr; } //获取结束行数 private int GetEndLineNum() { int endLineNum = -1; for (int i = this.FileText.Count - 1; i >= 0; i--) { if (("S1" == this.FileText[i].Substring(0, 2)) || ("S2" == this.FileText[i].Substring(0, 2)) || ("S3" == this.FileText[i].Substring(0, 2)) ) { endLineNum = i; break; } } return endLineNum; } //获取结束行的地址大小 private int GetEndAddr() { int endLineNum = 0; int endAddr; endLineNum = GetEndLineNum(); if (0 == endLineNum) { endAddr = 0; } else { endAddr = this.GetLineAddr(endLineNum); } return endAddr; } private byte GetS19LineChecksum(string line) { byte lineDataLen; int sum = 0; lineDataLen = Convert.ToByte(line.Substring(2, 2), 16); int len = line.Length; for (int i = 2; i < (lineDataLen << 1) + 2; i += 2) { sum += Convert.ToByte(line.Substring(i, 2), 16); } sum = 0xff - (sum & 0xff); //sum = temp - sum; return (byte)sum; } //获取S19标识的行的长度 private int GetLineLen(int line) { int lineLen; if ((line < this.FileText.Count) && (line >= 0) ) { lineLen = Convert.ToInt16(this.FileText[line].Substring(2, 2), 16); } else { lineLen = 0; } return lineLen; } //获取S19行的数据长度 private int GetLineDataLen(int line) { int lineLen; int lineAddrLen; int lineDataLen; lineLen = GetLineLen(line); lineAddrLen = this.GetLineAddrLen(line); lineDataLen = lineLen - lineAddrLen / 2 - 1; return lineDataLen; } public void AddHead(byte[] data, int size, byte fill) { string s19Head; //string line = ""; int lineLen; int lineDataLen; int lineAddrLen; int startAddr; int addLineNum; int dataIndex = 0; int insertIndex; int headLineNum = 0; s19Head = this.FileText[0].Substring(0, 2); if ("S0" == s19Head) { headLineNum = 1; } insertIndex = headLineNum; s19Head = this.FileText[headLineNum].Substring(0, 2); lineLen = Convert.ToByte(this.FileText[headLineNum].Substring(2, 2), 16); switch (s19Head) { case "S1": { lineAddrLen = 4; break; } case "S2": { lineAddrLen = 6; break; } case "S3": { lineAddrLen = 8; break; } default: { return; } } lineDataLen = lineLen - (lineAddrLen >> 1) - 1; startAddr = this.GetStartAddr(); if (size > startAddr) { return; } else { //需要增加的行数 向上取整 addLineNum = (size + lineDataLen - 1) / (lineDataLen); startAddr = startAddr - addLineNum * lineDataLen; for (int i = 0; i < addLineNum; i++) { //添加Sx和长度 string line = s19Head + this.ByteToStringHex((byte)lineLen); //添加地址 for (int j = 0; j < (lineAddrLen >> 1); j++) { int addrNum = (startAddr >> (((lineAddrLen >> 1) - j - 1) << 3)) & 0xff; line += this.ByteToStringHex((byte)addrNum); } startAddr += lineDataLen; //添加数据 for (int k = 0; k < lineDataLen; k++) { if (dataIndex < data.Length) { line += this.ByteToStringHex(data[dataIndex]); dataIndex++; } else { line += "FF"; } } //添加校验和 line += this.ByteToStringHex(this.GetS19LineChecksum(line)); //line += "\r\n"; this.FileText.Insert(insertIndex, line); insertIndex++; } } startAddr = GetStartAddr(); endAddr = GetEndAddr(); size = GetSize(); } public void AddEnd(byte[] data, int size, byte fill) { string s19Head; //string line = ""; int lineLen; int lineDataLen; int lineAddrLen; int addAddr; int addLineNum; int dataIndex = 0; int insertIndex; int endLineNum; int endLineLen; int endLineAddLen; char[] endLineTextData; endLineNum = this.GetEndLineNum(); insertIndex = endLineNum + 1; lineAddrLen = this.GetLineAddrLen(endLineNum); lineDataLen = this.GetLineDataLen(endLineNum - 1); endLineLen = this.GetLineLen(endLineNum); lineLen = this.GetLineLen(endLineNum - 1); s19Head = this.FileText[endLineNum].Substring(0, 2); //最后一行未满 if (endLineLen < lineLen) { if (size > (lineLen - endLineLen)) { endLineAddLen = lineLen - endLineLen; } else { endLineAddLen = size; } endLineTextData = this.FileText[endLineNum].Substring(0, endLineLen * 2 + 2).ToCharArray(); string temp = this.ByteToStringHex((byte)(endLineLen + endLineAddLen)); endLineTextData[2] = temp[0]; endLineTextData[3] = temp[1]; this.FileText[endLineNum] = new string(endLineTextData); for (int k = 0; k < endLineAddLen; k++) { if (dataIndex < data.Length) { this.FileText[endLineNum] += this.ByteToStringHex(data[dataIndex]); } else { this.FileText[endLineNum] += "FF"; } dataIndex++; size--; } //添加校验和 this.FileText[endLineNum] += this.ByteToStringHex(this.GetS19LineChecksum(this.FileText[endLineNum])); } //需要增加的行数 向上取整 addLineNum = (size + lineDataLen - 1) / (lineDataLen); //需要添加的地址 addAddr = this.GetEndAddr(); for (int i = 0; i < addLineNum; i++) { addAddr += lineDataLen; //添加Sx和长度 string line = s19Head + this.ByteToStringHex((byte)lineLen); //添加地址 for (int j = 0; j < (lineAddrLen >> 1); j++) { int addrNum = (addAddr >> (((lineAddrLen >> 1) - j - 1) << 3)) & 0xff; line += this.ByteToStringHex((byte)addrNum); } //添加数据 for (int k = 0; k < lineDataLen; k++) { if (dataIndex < data.Length) { line += this.ByteToStringHex(data[dataIndex]); dataIndex++; } else { line += "FF"; } } //添加校验和 line += this.ByteToStringHex(this.GetS19LineChecksum(line)); //line += "\r\n"; this.FileText.Insert(insertIndex, line); insertIndex++; } startAddr = GetStartAddr(); endAddr = GetEndAddr(); size = GetSize(); } public void ReadBinArray(string s19Head, byte[] data, int startAddr, int lineLen) { int addLineNum; int lineAddrLen; int lineDataLen; int addAddr; int dataIndex = 0; switch (s19Head) { case "S1": { lineAddrLen = 4; break; } case "S2": { lineAddrLen = 6; break; } case "S3": { lineAddrLen = 8; break; } default: { return; } } //需要添加的地址 addAddr = startAddr; lineDataLen = lineLen - (lineAddrLen >> 1) - 1; //需要增加的行数 向上取整 addLineNum = (data.Length + lineDataLen - 1) / (lineDataLen); this.FileText.Clear(); for (int i = 0; i < addLineNum; i++) { //添加Sx和长度 if ((data.Length - dataIndex) < (lineLen - 1))//最后一行数据未满 { lineDataLen = data.Length - dataIndex; lineLen = lineDataLen + (lineAddrLen >> 1) + 1; } string line = s19Head + this.ByteToStringHex((byte)lineLen); //添加地址 for (int j = 0; j < (lineAddrLen >> 1); j++) { int addrNum = (addAddr >> (((lineAddrLen >> 1) - j - 1) << 3)) & 0xff; line += this.ByteToStringHex((byte)addrNum); } //添加数据 for (int k = 0; k < lineDataLen; k++) { if (dataIndex < data.Length) { line += this.ByteToStringHex(data[dataIndex]); dataIndex++; } else { line += "FF"; } } //添加校验和 line += this.ByteToStringHex(this.GetS19LineChecksum(line)); //line += "\r\n"; //this.FileText.Insert(insertIndex, line); this.FileText.Add(line); addAddr += lineDataLen; } startAddr = GetStartAddr(); endAddr = GetEndAddr(); size = GetSize(); } } }