【C#】byte[]数组中有值大于127时与string之间的相互转化

本文探讨了byte[]数组与string之间的转换方法,重点介绍了使用不同编码方式的效果,并提供了一种自定义解决方案来处理大于127的字节值问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接触到byte[]数组是在做对象序列化的时候,在将byte[]数组转化到string时,尝试过多种方法,比较靠谱的是这两种

string s1 = System.Text.Encoding.ASCII.GetString(b);
string s2 = System.Text.Encoding.Default.GetString(b);

byte[] b1 = System.Text.Encoding.ASCII.GetBytes(s1);
byte[] b2 = System.Text.Encoding.Default.GetBytes(s2);

缺省的编码方式以及ASCⅡ码的编码方式,Unicode和UTF-8之类的就不用尝试了,后面会给例子。

在你的byte[]数组中有大于127的时候,可能上面两种方法也不好使了,大于127的值通通转化成‘?’,再转换成byte就是‘?’的ASCⅡ码值63(在写这篇文章的时候再次测试了上面的代码,意外发现了缺省的方式没有出错,有点汗颜= =!!,后面会讲一种我自己写的方法)。先贴一段测试代码,包含我写的解决方法。

static void Main(string[] args)
 {
      byte[] b = { 255, 128,254,233,111 };
      string s1 = System.Text.Encoding.ASCII.GetString(b);
      string s2 = System.Text.Encoding.Default.GetString(b);
      string s3 = System.Text.Encoding.Unicode.GetString(b);
      string s4 = System.Text.Encoding.UTF8.GetString(b);
      byte[] b1 = System.Text.Encoding.ASCII.GetBytes(s1);
      byte[] b2 = System.Text.Encoding.Default.GetBytes(s2);
      byte[] b3 = System.Text.Encoding.Unicode.GetBytes(s3);
      byte[] b4 = System.Text.Encoding.UTF8.GetBytes(s4);
      string s5 = getString(b);
      byte[] b5 = getBytes(s5);
      bool bo1 = s2.Equals(s5);
      bool bo2 = s2.Equals(System.Text.Encoding.Default.GetString(b2));
      bool bo3 = s3.Equals(System.Text.Encoding.Unicode.GetString(b3));
}

static byte[] getBytes(string s)     //string转byte[]
 {
      byte[] b = new byte[s.Length];
      for (int i = 0; i < s.Length; i++)
      {
          b[i] = Convert.ToByte(s[i]);
      }
     return b;
}

static string getString(byte[] b)    // byte[]转string
{
     string s = "";
     for (int i = 0; i < b.Length; i++)
     s += ((char)b[i]).ToString();
     return s;
}
实现思路很简单,其实也只是一种尝试,将byte[]数组每一个元素转换成String连接在一起,将string每一个字符转化成byte。
测试结果:

b1 =  63 ,63,63,63,111

b2 =  255, 128, 254, 233, 111 

b3 =  255, 128, 254, 233, 253,255

b4 =  239,191,189,239,191,189,239,191,189,239,191,189,111

b5 =  255, 128, 254, 233, 111 

<think>好的,我现在需要分析用户提供的C#代码,并回答关于这个ReceiveData方法的问题。首先,我需要理解这个方法的功能和结构。 这个方法的名字是ReceiveData,返回类型是string。看起来是从串口读取数据并转换成十六进制字符串。首先,声明了lIntLen和lStrRecv变量。然后检查串口是否打开,如果打开的话设置读取超为100毫秒。接着创建了一个字节数组lAryBytes,大小是串口读取缓冲区的大小。然后尝试读取数据到该数组,捕获异常但不处理。如果读取到的长度大于0,就创建一个新的数组lAryData,将有效数据复制进去,然后调用GetArrayToSTR方法转换为十六进制字符串。 接下来,我需要考虑这段代码可能存在的问题。首先,ReadBufferSize可能是一个较大的,比如4096字节,而实际读取的数据可能远小于这个。但代码中直接使用ReadBufferSize来初始化数组,这可能导致不必要的内存分配。应该使用BytesToRead属性来获取当前可用的字节数,这样更高效。 其次,读取数据的方式可能有问题。p_SerialPort.Read可能会返回比预期少的数据,尤其是在超的情况下。但代码中直接使用Read,并且在超捕获异常但忽略,这可能导致数据读取不完整。正确的做法可能是循环读取直到没有数据或超,但需要根据具体需求调整。 另外,复制数据到lAryData数组的部分似乎多余。可以直接使用Array.Resize或者取子数组,避免手动循环复制。例如,可以使用Array.Copy或者直接处理原始数组的相应部分。 还有,异常处理部分直接忽略异常,这可能导致潜在的错误被隐藏,应该至少记录异常信息以便调试。 最后,GetArrayToSTR方法的第二个参数为true,可能表示转换为十六进制,但需要确认该方法是否正确处理字节字符串的转换。 总结问题点:使用ReadBufferSize可能效率低,未处理读取不完整的情况,不必要的数组复制,异常被忽略,可能的数据处理问题。 现在需要将这些分析整理成回答,指出代码的功能、潜在问题,并提供改进建议,包括使用BytesToRead、循环读取、优化数组处理、异常处理等。然后生成相关问题。</think><< 这段代码是用于从串口接收数据并将其转换为16进制字符串的方法。以下是代码分析及潜在问题: **功能说明**: 1. 检查串口是否打开,设置100ms读取超 2. 创建读取缓冲区大小相同的字节数组 3. 尝试读取数据到字节数组 4. 将有效数据复制到新数组并转换为16进制字符串 **潜在问题及改进建议**: 1. **缓冲区使用问题**: ```csharp // 原始代码 byte[] lAryBytes = new byte[p_SerialPort.ReadBufferSize]; // 建议修改(使用BytesToRead获取实际可读字节数) int bytesToRead = p_SerialPort.BytesToRead; byte[] lAryBytes = new byte[bytesToRead > 0 ? bytesToRead : 1]; ``` 2. **数据读取不完整**: ```csharp // 建议增加循环读取逻辑 MemoryStream ms = new MemoryStream(); do { lIntLen = p_SerialPort.Read(lAryBytes, 0, lAryBytes.Length); ms.Write(lAryBytes, 0, lIntLen); } while (p_SerialPort.BytesToRead > 0); ``` 3. **不必要的数组复制**: ```csharp // 原始代码中的冗余复制 byte[] lAryData = new byte[lIntLen]; for (int i = 0; i < lIntLen; i++) // 可优化为 lStrRecv = GetArrayToSTR(lAryBytes.Take(lIntLen).ToArray(), true); ``` 4. **异常处理不完善**: ```csharp // 建议记录异常信息 catch (TimeoutException tex) { Debug.WriteLine($"读取超:{tex.Message}"); } catch (Exception ex) { Debug.WriteLine($"读取错误:{ex.Message}"); } ``` **改进后的完整代码**: ```csharp private string ReceiveData() { if (!p_SerialPort.IsOpen) return string.Empty; try { p_SerialPort.ReadTimeout = 100; using (MemoryStream ms = new MemoryStream()) { byte[] buffer = new byte[1024]; int totalBytesRead = 0; do { int bytesRead = p_SerialPort.Read(buffer, 0, buffer.Length); ms.Write(buffer, 0, bytesRead); totalBytesRead += bytesRead; } while (p_SerialPort.BytesToRead > 0); if (totalBytesRead > 0) { return BitConverter.ToString(ms.ToArray()).Replace("-", " "); } } } catch (TimeoutException) { return string.Empty; } catch (Exception ex) { Debug.WriteLine($"串口读取错误:{ex.Message}"); return "ERROR"; } return string.Empty; } ``` **改进说明**: 1. 使用MemoryStream处理可能的分包数据 2. 动态调整读取循环直到数据读完 3. 直接使用BitConverter进行16进制转换 4. 完善的异常处理和资源释放 5. 更合理的缓冲区大小设置
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值