请求实现点击Read按钮时将串口接收数据保存至TXT文件(附C#代码)
C# 实现点击Read按钮保存串口数据到TXT文件
嘿,我来帮你搞定这个需求!基于你提供的串口通信代码框架,我会帮你完成点击「Read」按钮时将串口接收的数据保存到TXT文件的功能,主要需要处理串口数据接收、按钮逻辑和文件写入这几个核心部分,下面是完整的实现方案:
完整修改后的代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Threading; using System.IO.Ports; using System.IO; namespace Serial { public partial class Form1 : Form { static SerialPort serialPort1; // 用来缓存接收的数据(可选,方便后续查看或批量写入) private StringBuilder receivedData = new StringBuilder(); // 标记当前是否正在保存数据 private bool isSaving = false; public Form1() { InitializeComponent(); getAvailablePorts(); serialPort1 = new SerialPort(); // 绑定串口数据接收的回调事件,收到数据就触发处理 serialPort1.DataReceived += SerialPort1_DataReceived; } // 你原有的获取可用串口方法,假设已经实现了端口列表加载逻辑 void getAvailablePorts() { string[] ports = SerialPort.GetPortNames(); // 比如把端口添加到下拉框:comboBox_Port.Items.AddRange(ports); } // 串口数据接收事件处理函数 private void SerialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { // 如果没在保存状态,直接返回 if (!isSaving) return; try { // 读取串口缓冲区里的所有数据 string newData = serialPort1.ReadExisting(); // 把新数据追加到缓存里 receivedData.Append(newData); // 跨线程写入文件(因为串口事件在后台线程,用Invoke确保安全) this.Invoke((MethodInvoker)delegate { // 用追加模式打开文件,避免覆盖原有内容,编码用UTF8保证兼容性 using (StreamWriter writer = new StreamWriter("串口数据记录.txt", true, Encoding.UTF8)) { // 加上时间戳,方便后续查看数据接收的时间点 writer.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss} | {newData}"); } }); } catch (Exception ex) { // 捕获异常并提示,避免程序崩溃 this.Invoke((MethodInvoker)delegate { MessageBox.Show($"数据处理出错:{ex.Message}", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); }); } } // Read按钮的点击事件(记得在窗体设计器里把按钮的Click事件绑定到这个方法) private void btnRead_Click(object sender, EventArgs e) { if (!isSaving) { // 未开始保存时,打开串口并启动监听 try { // 这里替换成你的串口参数配置,建议从UI控件(如下拉框、输入框)获取 serialPort1.PortName = comboBox_Port.Text; // 串口端口 serialPort1.BaudRate = 9600; // 波特率,根据设备实际设置 serialPort1.Parity = Parity.None; serialPort1.DataBits = 8; serialPort1.StopBits = StopBits.One; if (!serialPort1.IsOpen) { serialPort1.Open(); isSaving = true; btnRead.Text = "停止保存"; // 切换按钮文本 MessageBox.Show("已开始监听串口并保存数据!"); } } catch (Exception ex) { MessageBox.Show($"打开串口失败:{ex.Message}", "错误提示", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { // 已在保存状态时,停止监听并关闭串口 if (serialPort1.IsOpen) { serialPort1.Close(); } isSaving = false; btnRead.Text = "开始保存"; // 恢复按钮文本 MessageBox.Show("已停止保存,串口已关闭!"); // 可选:如果想把所有缓存的数据一次性写入文件,可以取消下面的注释 // using (StreamWriter writer = new StreamWriter("串口数据记录_批量.txt", false, Encoding.UTF8)) // { // writer.WriteLine($"=== 记录时间:{DateTime.Now:yyyy-MM-dd HH:mm:ss} ==="); // writer.Write(receivedData.ToString()); // } // receivedData.Clear(); // 清空缓存 } } // 窗体关闭时,确保释放串口资源 private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (serialPort1.IsOpen) { serialPort1.Close(); } } } }
核心功能说明
- 串口数据接收绑定:通过
SerialPort1_DataReceived事件监听串口数据,一旦有数据就自动触发读取和写入操作。 - 按钮状态切换:点击Read按钮会在“开始保存”和“停止保存”之间切换,同时控制串口的打开和关闭。
- 文件写入逻辑:使用
StreamWriter的追加模式写入文件,每条数据都加上时间戳,方便后续追溯;用Invoke处理跨线程操作,避免UI线程冲突。 - 资源安全:窗体关闭时自动关闭串口,防止资源泄漏。
一些需要注意的细节
- 一定要在窗体设计器里把Read按钮的
Click事件绑定到btnRead_Click方法,否则按钮点击不会生效。 - 串口参数(端口、波特率等)要和你的设备完全匹配,建议做成可在UI上配置的控件,比如用下拉框选端口,输入框设置波特率。
- 默认文件保存在程序运行的目录下,如果你想让用户选择保存路径,可以添加
SaveFileDialog控件来实现。 - 代码里提供了两种写入方式:实时写入和批量写入,你可以根据需求选择其中一种。
内容的提问来源于stack exchange,提问作者quyet
相关产品推荐
相关产品推荐

