当前位置: 首页 > 编程日记 > 正文

C#winform上位机开发学习笔记3-串口助手的信息保存功能添加

1.功能描述

下次开启串口助手时会存留上次的发送框信息,以及选择的串口号(备份串口号与发送栏内容

原理:将文本信息保存在,ini文件中,下次打开软件时读取文件信息刷新对应控件文本

注意:在窗口关闭事件函数中也可进行信息备份工作,但不稳定,因此用本篇中的方法进行较为可靠

2.代码部分

2.1 创建文件与编辑写入信息存储代码

2.1.1 public partial class Form1 : Form初始化程序中加入以下代码

using System.Runtime.InteropServices;//应用空间变量声明,未声明则出现[DllImport("kernel32")]报错

public partial class Form1 : Form
    {
        //信息保存功能
        [DllImport("kernel32")]
        //写文件函数
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);//系统dll导入ini写函数
        [DllImport("kernel32")]
        //读文件函数
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);//系统dll导入ini读函数
        //创建文件,文件名为:Backup.ini
        string FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Backup.ini";
    }

 #存储的文件保存在bin文件中,文件名为创建时编辑的名称“Backup.ini”

2.1.2 串口发送栏函数

备份发送栏

 //串口发送栏函数
        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            //备份发送栏
            WritePrivateProfileString("串口1", "发送栏", textBox5.Text, FileName);//保存文件:其中串口1与发送栏为文本内的标识,将发送栏的信息存储在filename文件中
        }

2.1.3 手动扫描并添加串口号函数中添加备份串口号程序

备份串口号

 //备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中

手动扫描并添加串口号函数完整代码如下:

        //自定义函数1-手动扫描并添加可用串口
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
            string[] ComputerPortName = SerialPort.GetPortNames();  //获取本机串口列表
            //string BackupPort;//定义字符串备份端口号

            bool MyBackupPortFlag = false;  //备份端口号可用标志位

            //恢复端口号
            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();//定义字符串备份端口号

            //添加端口号
            MyBox.Items.Clear();  //清空ComboBox内容
            for (int i = 0; i < ComputerPortName.Length; i++) //循环
            {
                if (MyBackupPortName == ComputerPortName[i])  //之前的端口号可用,置位标志位
                {
                    MyBackupPortFlag = true;
                }

                try  //核心原理是依靠try和catch完成遍历
                {
                    MyPort.PortName = ComputerPortName[i];
                    MyPort.Open();                          //如果失败,后面的代码不会执行          
                    MyBox.Items.Add(MyPort.PortName);       //打开成功,添加至下拉列表
                    MyPort.Close();                         //关闭

                    //检测备份端口号是否有效,端口号初始化为备份端口号
                    if (MyBackupPortName == MyPort.PortName)
                    {
                        comboBox1.Text = MyBackupPortName;
                    }
                    //如果备份端口号无效,端口号初始化为第一个可用端口号
                    if (comboBox1.Text == " ")
                        comboBox1.Text = MyPort.PortName;
                }
                catch
                {

                }
            }
            //端口号赋初值
            if (MyBackupPortFlag == true)
            {
                MyBox.Text = MyBackupPortName; //添加备份的端口号
            }
            else
            {
                if (ComputerPortName.Length > 0)
                {
                    MyBox.Text = ComputerPortName[ComputerPortName.Length - 1]; //添加数值大的端口号
                }
                else
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("没有检测到串口工具!\r\n");
                }
            }
            //备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }

复选框函数中也添加此程序代码

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {//备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }

复选框函数万整改代码如下:

        //串口开启状态下切换串口号
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) //串口已打开,此时关闭串口 
            {
                serialPort1.Close();                       //打开端口
                try
                {
                    serialPort1.PortName = comboBox1.Text;    //端口号
                    serialPort1.Open();                       //打开端口
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换成功!\r\n");

                    WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);
                }
                catch
                {
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换失败!\r\n");
                }
            }
            //备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }

2.2 编写读取文件赋值文本代码

2.2.1 恢复发送栏

2.2.1.1 初始化函数中加入下述代码
    public partial class Form1 : Form
    {
        //定义字符串用于存储读出的.ini文件中的内容变量,大小为100个字节
        StringBuilder BackupBuf = new StringBuilder(100);
    }
2.2.1.2 窗体装载函数中加入下述代码
        //窗体装载函数
        private void Form1_Load(object sender, EventArgs e)
        {
            //恢复发送栏
            //获取FileName中存储在BackupBuf中内存为100字节的标识为"串口1", "发送栏"的变量,恢复内容若没有则获取空字符
            GetPrivateProfileString("串口1", "发送栏", "", BackupBuf, 100, FileName);
            textBox5.Text = BackupBuf.ToString();//获取后将其转换为字符串赋值给发送栏
        }
2.2.3 恢复时判断存储的端口号是否有效,有效则恢复存储文件的端口号,无效则恢复为首端口号
        //自定义函数1-手动扫描并添加可用串口
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
             //恢复端口号
            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();//定义字符串备份端口号
        
            //检测备份端口号是否有效,端口号初始化为备份端口号
            if (MyBackupPortName == MyPort.PortName)
             {
                 comboBox1.Text = MyBackupPortName;
             }
            //如果备份端口号无效,端口号初始化为第一个可用端口号
            if (comboBox1.Text == " ")
                 comboBox1.Text = MyPort.PortName;   
        }         

手动扫描并添加串口号函数完整代码如下:

        //自定义函数1-手动扫描并添加可用串口
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
            string[] ComputerPortName = SerialPort.GetPortNames();  //获取本机串口列表
            //string BackupPort;//定义字符串备份端口号

            bool MyBackupPortFlag = false;  //备份端口号可用标志位

            //恢复端口号
            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();//定义字符串备份端口号

            //添加端口号
            MyBox.Items.Clear();  //清空ComboBox内容
            for (int i = 0; i < ComputerPortName.Length; i++) //循环
            {
                if (MyBackupPortName == ComputerPortName[i])  //之前的端口号可用,置位标志位
                {
                    MyBackupPortFlag = true;
                }

                try  //核心原理是依靠try和catch完成遍历
                {
                    MyPort.PortName = ComputerPortName[i];
                    MyPort.Open();                          //如果失败,后面的代码不会执行          
                    MyBox.Items.Add(MyPort.PortName);       //打开成功,添加至下拉列表
                    MyPort.Close();                         //关闭

                    //检测备份端口号是否有效,端口号初始化为备份端口号
                    if (MyBackupPortName == MyPort.PortName)
                    {
                        comboBox1.Text = MyBackupPortName;
                    }
                    //如果备份端口号无效,端口号初始化为第一个可用端口号
                    if (comboBox1.Text == " ")
                        comboBox1.Text = MyPort.PortName;
                }
                catch
                {

                }
            }
            //端口号赋初值
            if (MyBackupPortFlag == true)
            {
                MyBox.Text = MyBackupPortName; //添加备份的端口号
            }
            else
            {
                if (ComputerPortName.Length > 0)
                {
                    MyBox.Text = ComputerPortName[ComputerPortName.Length - 1]; //添加数值大的端口号
                }
                else
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("没有检测到串口工具!\r\n");
                }
            }
            //备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }

3.涉及到的相关完整代码

    public partial class Form1 : Form
    {
        //信息保存功能
        [DllImport("kernel32")]
        //写文件函数
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);//系统dll导入ini写函数
        [DllImport("kernel32")]
        //读文件函数
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);//系统dll导入ini读函数
        //创建文件,文件名为:Backup.ini
        string FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Backup.ini";
        //定义字符串用于存储读出的.ini文件中的内容变量,大小为100个字节
        StringBuilder BackupBuf = new StringBuilder(100);
         public Form1()
        {
            InitializeComponent();
            //串口接收支持中文显示
            serialPort1.Encoding = Encoding.GetEncoding("GB2312");  //串口1的解码支持GB2312汉字
            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;//检查跨线程出错解决方法
        }
        //窗体装载函数
        private void Form1_Load(object sender, EventArgs e)
        {
            SearchAndAddSerialToComboBox(serialPort1, comboBox1);//扫描端口号,并将可用端口添加至下拉列表
            comboBox14.Text = "115200";                           //默认显示值
            this.button2.PerformClick();                         //自动打开串口

            //恢复发送栏
            //获取FileName中存储在BackupBuf中内存为100字节的标识为"串口1", "发送栏"的变量,恢复内容若没有则获取空字符
            GetPrivateProfileString("串口1", "发送栏", "", BackupBuf, 100, FileName);
            textBox5.Text = BackupBuf.ToString();//获取后将其转换为字符串赋值给发送栏
      
        }

         //自定义函数1-手动扫描并添加可用串口
        private void SearchAndAddSerialToComboBox(SerialPort MyPort, ComboBox MyBox)
        {
            string[] ComputerPortName = SerialPort.GetPortNames();  //获取本机串口列表
            //string BackupPort;//定义字符串备份端口号

            bool MyBackupPortFlag = false;  //备份端口号可用标志位

            //恢复端口号
            GetPrivateProfileString("串口1", "端口号", "", BackupBuf, 100, FileName);  //获取备份的端口号
            string MyBackupPortName = BackupBuf.ToString();//定义字符串备份端口号

            //添加端口号
            MyBox.Items.Clear();  //清空ComboBox内容
            for (int i = 0; i < ComputerPortName.Length; i++) //循环
            {
                if (MyBackupPortName == ComputerPortName[i])  //之前的端口号可用,置位标志位
                {
                    MyBackupPortFlag = true;
                }

                try  //核心原理是依靠try和catch完成遍历
                {
                    MyPort.PortName = ComputerPortName[i];
                    MyPort.Open();                          //如果失败,后面的代码不会执行          
                    MyBox.Items.Add(MyPort.PortName);       //打开成功,添加至下拉列表
                    MyPort.Close();                         //关闭

                    //检测备份端口号是否有效,端口号初始化为备份端口号
                    if (MyBackupPortName == MyPort.PortName)
                    {
                        comboBox1.Text = MyBackupPortName;
                    }
                    //如果备份端口号无效,端口号初始化为第一个可用端口号
                    if (comboBox1.Text == " ")
                        comboBox1.Text = MyPort.PortName;
                }
                catch
                {

                }
            }
            //端口号赋初值
            if (MyBackupPortFlag == true)
            {
                MyBox.Text = MyBackupPortName; //添加备份的端口号
            }
            else
            {
                if (ComputerPortName.Length > 0)
                {
                    MyBox.Text = ComputerPortName[ComputerPortName.Length - 1]; //添加数值大的端口号
                }
                else
                {
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("没有检测到串口工具!\r\n");
                }
            }
            //扫描后写入备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }
        //自定义函数2-CRC校验
        private UInt16 Crc_Check(byte[] Data, byte DataLEN)
        {
            UInt16 CRC = 0xFFFF;

            for (byte i = 0; i < DataLEN; i++)
            { 
                CRC ^= Data[i];
                for(byte j = 0; j < 8; j++)
                {
                    if((CRC & 0x0001) == 0x0001)
                    {
                        CRC = (UInt16)((CRC >> 1) ^ 0xA001);
                    }
                    else
                    {
                        CRC = (UInt16)(CRC >> 1);
                    }
                }
            }
            CRC = (UInt16)((CRC >> 8) + (CRC<<8));
            return CRC;
        }
        //串口开启状态下切换串口号
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen) //串口已打开,此时关闭串口 
            {
                serialPort1.Close();                       //打开端口
                try
                {
                    serialPort1.PortName = comboBox1.Text;    //端口号
                    serialPort1.Open();                       //打开端口
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换成功!\r\n");

                    WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);
                }
                catch
                {
                    serialPort1.Close();
                    button2.BackgroundImage = Properties.Resources.Image_CloseSerial;
                    button2.Tag = "OFF";
                    textBox1.AppendText("[" + DateTime.Now.ToString("HH:mm:ss") + "]" + "->");
                    textBox1.AppendText("串口更换失败!\r\n");

                    timer1.Stop();
                }
            }
            //复选框选择后备份端口号
            WritePrivateProfileString("串口1", "端口号", comboBox1.Text, FileName);//保存文件:其中串口1与端口号为文本内的标识,将COM组合框的信息存储在filename文件中
        }
        //串口发送栏函数
        private void textBox5_TextChanged(object sender, EventArgs e)
        {
            //备份发送栏
            WritePrivateProfileString("串口1", "发送栏", textBox5.Text, FileName);//保存文件:其中串口1与发送栏为文本内的标识,将发送栏的信息存储在filename文件中
        }
}

4.测试结果

关闭软件后重新打开发送框与com口选择框出现关闭前输入的信息,功能添加成功

此功能涉及到的代码较多,且多与其他功能函数相关,总体的逻辑为创建文件->将需要备份的信息存储在文件内->下次开启软件后自动从备份的文件中读取信息并赋值到相关的文本中,从而达到信息保存的目的

注:参考自B站硬件家园

相关文章:

一个合格的Java选手必须要掌握的并发锁知识

Java内置锁:基于Java语法层面(关键词)实现的锁,主要是根据Java语义来实现,最典型的应用就是synchronized。Java显式锁:基于JDK层面实现的锁,主要是根据基于Lock接口和ReadWriteLock接口,以及统一的AQS基础同步器等来实现,最典型的有ReentrantLock。使用方式:synchronized关键字互斥锁主要有作用于对象方法上面,作用于类静态方法上面,作用于对象方法里面,作用于类静态方法里面等4种方式。

Integer.toHexString(b & 0xff)理解以及& 0xff什么意思

首先toHexString传的参数应该是int类型32位,此处传的是byte类型8位,所以前面需要补24个0。然后& 0xff 就是把前面24个0去掉只要后8位。toHexString(b & 0xff)相当于做了一次位的与运算,将前24位字符省略,将后8位保留。是两个十六进制的数,每个f用二进制表示是1111,所以占四位(bit),两个f()占八位(bit),八位(bit)也就是一个字节(byte).这个方法是把字节(转换成了int)以16进制的方式显示。我的理解是这样,如有不对欢迎指正!

深度学习硬件基础:CPU与GPU

CPU:叫做中央处理器(central processing unit)作为计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元。[^3]可以形象的理解为有25%的ALU(运算单元)、有25%的Control(控制单元)、50%的Cache(缓存单元)GPU:叫做图形处理器。

YOLOv8-Detect训练CoCo数据集+自己的数据集

至此,整个训练预测阶段完成。此过程同样可以在linux系统上进行,在数据准备过程中需要仔细,保证最后得到的数据准确,最好是用显卡进行训练。有问题评论区见!

【OpenCV】在Linux上使用OpenCvSharp

OpenCvSharp是一个OpenCV的 .Net wrapper,应用最新的OpenCV库开发,使用习惯比EmguCV更接近原始的OpenCV,该库采用LGPL发行,对商业应用友好。

svn和git的本质区别是什么

上边图中,跨越了区的箭头,它中间的区数据都会同步。例如:git checkout ,它是将本地仓库数据更新到暂存区和工作区的。

使用JavaScript实现复杂功能:一个完整的电商网站搜索功能

随着互联网的发展,电子商务网站已经成为人们购物的重要平台。而在这些网站中,搜索功能无疑是核心功能之一。用户可以通过搜索快速找到他们需要的商品,从而提高购物体验。本文将详细介绍如何使用JavaScript实现一个完整的电商网站搜索功能。

C++并发编程:互斥锁std::mutex和lock_guard的使用

对象离开其作用域时,会自动调用析构函数,该析构函数会释放锁。这确保了在任何情况下(包括由于异常等原因导致的提前退出),锁都会被正确释放,从而避免了忘记手动释放锁而导致的死锁问题。mutex 用于控制多个线程访问共享资源,确保在任意时刻只有一个线程可以访问该资源,避免数据竞争。这确保了同一时刻只有一个线程可以访问被保护的资源,从而防止多线程并发访问导致的数据不一致性。是 C++ 标准库中提供的一个模板类,用于在其构造时自动获取锁,在析构时自动释放锁。是 C++ 标准库中提供的一种用于多线程同步的互斥锁实现。

上位机图像处理和嵌入式模块部署(qt插件的使用)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 一个软件一般有很多的功能,但是主流程只有一个。但在软件开发的过程当中,一般来说功能是需要不断添加的,但是主流程最好不要轻易修改。这里的插件就相当于各种各样的功能,而主流程就是如何怎么去调用这些插件的功能。所以,今天正好来学一下怎么添加qt插件,个人觉得这部分还是非常重要的。

C程序的内存空间布局(栈、堆、数据区、常量区、代码区)

较详细的介绍了栈、堆、数据区、常量区、代码区

NRF24L01模块传输MPU6050数据,接收端数据一直为0问题记录

问题描述:一、发射端1、正确配置NRF模块,以及测试过能够正常通信,在发射端的发射线程中进行了如下操作2、这里是获取了陀螺仪的x轴数据,将其而分为两个8位的数据存入发送缓冲区中。因为一个陀螺仪x轴数据是16位的,所以对其进行了拆分,这里只获取gyro的x轴数据进行发送,目的是进行测试。3、这个是发送函数,只要把发送缓冲区的地址作为参数传入就可以发送了。二、接收端1、接收端的NRF24L01模块也正确配置后,在接收线程中进行如下操作2、读取NRF传输过来的数据,存到接收BUF中,然后打印

Java中的四种访问权限(private,public,protected,无修饰)

/实体类属性和数据库字段名称不一致//实体类属性和数据库字段名称不一致return id;return age;emp.test();//直接调用public修饰的变量//private修饰的变量进行赋值//调用private修饰的变量1、public修饰符定义的属性和方法通过对象实例化进行调用,2、private修饰的属性通过set、get方法进行调用。

YOLOv5中Ghostbottleneck结构shortcut=True和shortcut=False有什么区别

GhostBotleneck结构中的shodcut=True和shorcut=False的区别在干是否使用残差连接。当shorcu=True时,使用残差连接,可以以加速模型的收敛速度和提高模型的准确率,当shorcu=False时,不使用残差连接,可以减少模型的参数数量和计算量。实际上不只是Ghostbottleneck具有残差连接,在C3、C2f等具有Bottleneck模块的结构均可根据此例举一反三。残差块是深度卷积神经网络中的一种基本模块,可以有效地解决梯度消失和梯度爆炸的问题。

Java中的方法重载和方法重写有什么区别?

Java中的方法重载(Overloading)和方法重写(Overriding)都是面向对象编程中的重要概念,但它们之间有一些区别。方法重载是指在同一个类中,可以定义多个具有相同名称但参数列表不同的方法。这些方法具有不同的参数类型、参数个数或参数顺序。在调用重载方法时,Java编译器会根据传递给方法的参数类型和数量来选择要调用的正确方法。方法重载主要用于解决方法的命名冲突和提高代码的可读性和可维护性。

python基础使用之变量,表达式,语句

PYTHON基础知识系列之变量、表达式、语句

C语言常见面试题:什么是宏,宏的作用是什么?

宏在计算机科学中是一种批量处理程序命令,它是一种抽象的规则或模式,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串)。在编译时,预处理器会对宏进行展开,即将宏的内容替换到宏所在的位置。以上是宏的一些主要作用,但并不是全部。在实际编程中,根据需要选择是否使用宏以及如何使用宏,以实现更好的代码组织和可读性。,这样就可以计算出a和b的和。这个例子展示了宏的基本用法和作用。在这个例子中,我们定义了一个宏。,用于计算两个数的和。时,预处理器会将其展开为。

python基础小知识:引用和赋值的区别

通过引用,就可以在程序范围内任何地方传递大型对象而不必在途中进行开销巨大的赋值操作。不过需要注意的是,这种赋值仅能做到顶层赋值,如果出现嵌套的情况下仍不能进行深层赋值。赋值与引用不同,复制后会产生一个新的对象,原对象修改后不会影响到新的对象。如果在原位置修改这个可变对象时,可能会影响程序其他位置对这个对象的引用

在C#中调用C++函数并返回const char*类型的值

在C#中,使用DllImport特性将C++函数声明为外部函数。在Main方法中,调用generateProjectCode函数并将返回的指针转换为const char*类型的字符串。在C#中调用C++函数并返回const char*类型的值,可以使用Interop服务来实现。C++代码需要编译为动态链接库(DLL)。

基于深度学习的细胞感染性识别与判定

通过引入深度学习技术,我们能够更精准地识别细胞是否受到感染,为医生提供更及时的信息,有助于制定更有效的治疗方案。基于深度学习的方法通过学习大量样本,能够自动提取特征并进行准确的感染性判定,为医学研究提供了更高效和可靠的手段。通过引入先进的深度学习技术,我们能够实现更快速、准确的感染性判定,为医学研究和临床实践提供更为可靠的工具。其准确性和效率将为医学研究带来新的突破,为疾病的早期诊断和治疗提供更可靠的支持。通过大规模的训练,模型能够学到细胞感染的特征,并在未知数据上做出准确的预测。

Golang 搭建 WebSocket 应用(八) - 完整代码

本文应该是本系列文章最后一篇了,前面留下的一些坑可能后面会再补充一下,但不在本系列文章中了。

Python自动化实战之接口请求的实现

作为一位过来人也是希望大家少走一些弯路,如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。

前端JS代码中Object类型数据的相关知识

遍历JavaScript中的对象有几种方法,包括使用for…in循环、Object.keys()方法、Object.values()方法和Object.entries()方法。因此前端传入了日期类型数据之后,如果和后台数据库中的数据类型不一致,比如数据库中的日期数据类型格式是。前端传入的Object对象中其中某个字段值是日期类型的数据,则在前端的类型就是一个。,则数据传往后端之前需要做格式类型转换。,它的值是一个中国标准时间,比如。

C# 实现单线程异步互斥锁

C#对异步的支持越来越成熟,async、await简化了代码也提高了可读性,但由于在一段上下文中有了异步操作,意味着这段操作可能会被同时重复调用,如果本身没有被设计可以重复调用的情况下,就很可能会出问题。以上就是今天要讲的内容,本文简单的实现了单线程的异步互斥锁,实现起来相对简单,但作用还是比较大的。虽然说有些情况的异步是可以在前期设计上避免同时调用,比如登录按钮点击后出现蒙板不允许再次点击,但是对于已存在的代码出现了同时调用问题,此时有互斥锁则可以避免大范围改动代码,有效解决问题。_c#实现线程都要经过一个阻塞的方法,线程之间互不干涉

Rust之旅 - Rust概念、Windows安装、环境配置

本章节介绍Rust概念、Windows安装、环境配置以及最初级的语法。至此,我们就成功的构建了一个Rust程序,并成功在Visual Studio Code里运行了这个程序,万事俱备,我们就可以开始Rust之旅了。资料获取,更多粉丝福利,关注下方公众号获取。

C语言中常用的字符串处理函数和内存操作函数

`memmove(void *destination, const void *source, size_t num)`:将`source`指向的内存块的前`num`个字节移动到`destination`所指向的内存块,即使内存块有重叠部分。返回指向`destination`的指针。- `memcpy(void *destination, const void *source, size_t num)`:将`source`指向的内存块的前`num`个字节复制到`destination`所指向的内存块。

Redis的key过期策略是怎么实现的

这是一道经典的Redis面试题,一个Redis中可能存在很多很多的key,这些key中可能有很大一部分都有过期时间,此时Redis服务器咋知道哪些key已经过期,哪些还没过期呢?如果直接遍历所有的key,这显然是行不通的,效率非常低!!Redis整体的策略是定期删除和惰性删除相结合。举个栗子:假如我去小卖铺买东西,付款的时候,发现东西过期了。就告知老板,于是老板下架此产品。消费者发现过期了,才去下架,这就叫。小卖铺老板主动定期抽取一部分商品,进行筛查,这就叫定期删除。

一键式Excel分词统计工具:如何轻松打包Python脚本为EXE

最近,表姐遇到了一个挑战:需要从Excel文件中统计出经过分词处理的重复字段,但由于数据隐私问题,这些Excel文件不能外传。这种情况下,直接使用Excel内置功能好像是行不通的,需要借助Python脚本来实现。为了解决这个问题,我写了一个简单的数据分析和自动化办公脚本,以方便使用。想象一下,即使电脑上没有安装Python,也能通过一个简单的EXE文件轻松完成工作,这是多么方便!因此,我决定不仅要写出这个脚本,还要学会如何将其打包成一个独立的EXE文件。这样,无需Python环境的电脑也能直接运行它

深入解析JavaScript的原生原型

在JavaScript中,除了自定义对象,还存在很多由JavaScript语言本身提供的原生对象。这些原生对象同样基于原型继承机制,拥有自己的原型。理解原生对象的原型非常重要,可以让我们正确使用这些内置对象,也有助于进一步理解JavaScript的原型继承系统。本文将详细解析原生对象的原型结构,揭开一些常见原生对象原型的神秘面纱。​学习原生对象的原型关系,有助于我们在日常开发中正确理解和使用这些JavaScript内置对象,避免一些常见陷阱。

深入三目运算符:JavaScript、C++ 和 Python 比较

三目运算符是编程中常用的条件表达式,它允许我们根据条件选择不同的值。我们将通过具体的例子分别介绍 JavaScript、C++ 和 Python 中的三目运算符,以便更好地理解它们的用法和特性。JavaScript 示例// 例子: 根据条件选择不同的值var x = 10;var y = 20;"x 大于 y" : "x 不大于 y";在这个例子中,如果x大于y,则result的值为 “x 大于 y”,否则为 “x 不大于 y”。C++ 示例// 例子: 根据条件选择不同的值。

Java中的4种引用类型,你知道几种?

Java作为一门面向对象的编程语言,内存管理一直是程序员需要关注的重要方面。在Java中,垃圾回收机制负责自动管理内存,而引用类型则是垃圾回收的重要参考。本文将深入讨论Java中的四种引用类型:强引用、弱引用、软引用和虚引用,以及它们在内存管理中的应用和区别。