如何将串口接收的原始数据写入.txt文件(C#+STM32场景)
解决C#串口接收原始二进制数据并写入文件的问题
问题根源
原代码使用StreamWriter和ReadExisting()是针对文本数据的处理方式,而摄像头通过UART发送的是二进制原始数据,用文本方式处理会导致数据损坏:
serialPort1.ReadExisting()会将串口接收的字节转换为字符串,过程中不符合UTF-8编码的字节会被替换为默认的替换字符(如�),丢失原始数据。StreamWriter会再次将字符串按UTF-8编码转换为字节写入文件,进一步破坏原始数据。
解决方案:直接处理二进制字节
要保留原始数据,需要直接读取串口的字节数组,并用二进制写入方式保存到文件,推荐使用FileStream来实现。
方案1:使用DataReceived事件实时接收(推荐)
串口数据是流式传输,点击按钮单次读取容易丢失数据,用DataReceived事件可以实时响应串口数据到达:
- 先在窗体初始化时注册事件:
public YourForm() { InitializeComponent(); serialPort1.DataReceived += SerialPort1_DataReceived; }
- 实现事件处理函数:
private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { SerialPort sp = (SerialPort)sender; int byteCount = sp.BytesToRead; byte[] buffer = new byte[byteCount]; // 读取原始字节数组 sp.Read(buffer, 0, byteCount); // 以二进制模式写入文件,FileMode.Append表示追加数据,Create则覆盖原有文件 using (FileStream fs = new FileStream("camera_data.bin", FileMode.Append, FileAccess.Write)) { fs.Write(buffer, 0, buffer.Length); } } catch (Exception ex) { MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
方案2:按钮触发单次读取(适合测试)
如果坚持用按钮触发读取,修改原按钮点击事件代码:
private void btnReceive_Click(object sender, EventArgs e) { try { if (serialPort1.IsOpen) { int byteCount = serialPort1.BytesToRead; if (byteCount <= 0) return; byte[] buffer = new byte[byteCount]; // 读取当前缓冲区的所有原始字节 serialPort1.Read(buffer, 0, byteCount); // 写入二进制文件 using (FileStream fs = new FileStream("camera_data.bin", FileMode.Append, FileAccess.Write)) { fs.Write(buffer, 0, buffer.Length); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
关键说明
- 保存的文件后缀建议用
.bin而非.txt,因为这是二进制数据,用文本编辑器打开会显示乱码,后续还原图像时直接读取该二进制文件即可。 - Docklight能正常接收是因为它默认处理的是原始二进制数据,没有经过文本编码转换,和上述方案的逻辑一致。
内容的提问来源于stack exchange,提问作者JoeLasagne
相关产品推荐
相关产品推荐

