c++QT文件IO

1、QFileDialog文件对话框

与QMessageBox一样,QFileDialog也继承了QDialog类,直接使用静态成员函数弹窗。弹出的结果(选择文件的路径)通过返回值获取。

1)获取一个打开或保存的文件路径

// 获取一个打开或保存的文件路径
// 参数1:父对象(this)
// 参数2:标题(执行操作:打开/保存)
// 参数3:在哪个目录中打开,默认值表示项目的工作目录
// 参数4:文件过滤器(过滤文件类型)
QString filter = "所有文件(*.*);;Qt(*.cpp *.h *.ui *.pro)";//文件过滤器
// 返回值:选择的文件路径,如果选择失败,返回空字符
QString QFileDialog:: getOpenFileName(
    QWidget * parent = 0,const QString & caption = QString(),const QString & dir = QString(), const QString & filter = QString())[static]QString QFileDialog:: getSaveFileName(
    QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString())[static]

需要注意的是,QFileDialog只是一个窗口类,本身不具备任何IO的能力。

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{
    ui->setupUi(this);connect(ui->pushButtonOpen,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));connect(ui->pushButtonSave,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));
}
Dialog::~Dialog()
{delete ui;
}
void Dialog::btnClickedSlot()
{if(ui->pushButtonOpen == sender()){
        QString filter = "所有文件(*.*);;Qt(*.cpp *.h *.ui *.pro)";
        QString path = QFileDialog::getOpenFileName(this,"打开","D:/",filter);if(path != ""){
            ui->textBrowserOpen->append(path);
            readPath = path;}else if(readPath == ""){QMessageBox::warning(this,"提示","请选择要打开的文件");}}else if(ui->pushButtonSave == sender()){
        QString filter = "所有文件(*.*);;Qt(*.cpp *.h *.ui *.pro)";
        QString path = QFileDialog::getSaveFileName(this,"保存","D:/",filter);if(path != ""){
            ui->textBrowserSave->append(path);
            writePath = path;}else if(writePath == ""){QMessageBox::warning(this,"提示","请选择保存的文件");}}else if(ui->pushButtonCopy == sender()){}
}

2、QFileInfo 文件信息类

只需要创建出对象后,通过各种成员函数直接获取文件信息。

部分函数如下:

1)构造函数

// 构造函数
// 参数为文件路径,如果文件非法,仍然可以创建出QFileInfo对象。
QFileInfo:: QFileInfo(const QString & file)

2)判断文件是否存在

// 判断文件是否存在
// 如果存在返回true、如果不存在返回false
bool QFileInfo:: exists() const

3)返回文件大小,如果不存在返回0

// 返回文件大小,如果不存在返回0
qint64 QFileInfo:: size() const

4)返回基础文件名,不包含后缀

// 返回基础文件名,不包含后缀
QString QFileInfo:: baseName() const

5)获取文件最后修改日期

// 获取文件最后修改日期
QDateTime QFileInfo:: lastModified() const

6)获取文件可读性

// 获取文件可读性
// 返回值为ture可读否则不可读
bool QFileInfo:: isReadable() const

#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    connect(ui->pushButtonOpen,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));
    connect(ui->pushButtonSave,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));
}
Dialog::~Dialog()
{
    delete ui;
}
void Dialog::printFileInfo()
{
    //创建文件对象
    QFileInfo fileInfo(readPath);
    if(!fileInfo.exists())
    {
        QMessageBox::warning(this,"提示","无效文件");
        return;
    }
    //获取文件大小
    qint64 fileSize = fileInfo.size();
    QString text = QString::number(fileSize);//int类型转QString类型
    text.prepend("文件大小:").append("字节");//prepend()在text前面插入字符,append()在text后面添加字符
    ui->textBrowserOpen->append(text);
    //获取文件名称
    text = fileInfo.baseName();//前面的text已经打印,重新用只需要覆盖即可。
    text.prepend("文件名称:");
    ui->textBrowserOpen->append(text);
    //获取文件最后修改日期
    text = fileInfo.lastModified().toString("修改日期:yyyy-MM-dd:hh-mm-ss");//获取后直接转为QString类型
    ui->textBrowserOpen->append(text);
    //文件可读性
    bool result = fileInfo.isReadable();//返回值为bool类型
    if(result)
    {
        ui->textBrowserOpen->append("文件可读");
    }
    else
    {
        ui->textBrowserOpen->append("文件不可读");
    }
}
void Dialog::btnClickedSlot()
{
    if(ui->pushButtonOpen == sender())
    {
        QString filter = "所有文件(*.*);;Qt(*.cpp *.h *.ui *.pro)";
        QString path = QFileDialog::getOpenFileName(this,"打开","D:/",filter);
        if(path != "")
        {
            ui->textBrowserOpen->append(path);
            readPath = path;
            printFileInfo();
        }
        else if(readPath == "")
        {
            QMessageBox::warning(this,"提示","请选择要打开的文件");
        }
    }
    else if(ui->pushButtonSave == sender())
    {        QString filter = "所有文件(*.*);;Qt(*.cpp *.h *.ui *.pro)";
        QString path = QFileDialog::getSaveFileName(this,"保存","D:/",filter);
        if(path != "")
        {
            ui->textBrowserSave->append(path);
            writePath = path;
        }
        else if(readPath == "")
        {
            QMessageBox::warning(this,"提示","请选择要保存的文件");
        }
    }
    else if(ui->pushButtonCopy == sender())
    {    }
}

3、QFile文件读写类

在Qt中所有IO类都继承自QIODevice类,QIODevice类中规定了最基础的IO相关的接口。这些接口虽然在不同的派生类中可能实现有所不同,但是调用方式一致。

1)QFile文件读写类构造函数

// 构造函数
// 参数为文件路径,如果是非法路径,也能创建出QFile对象,但是不能正常IO输入输出操作。
QFile:: QFile(const QString & name)

2)判断QFile对应的文件是否存在

// 判断QFile对应的文件是否存在
bool QFile:: exists() const

3)打开数据流

// 打开数据流
// 参数为打开的模式,只读模式、只写模式、读写模式等等
// 返回值:打开的结果
bool QIODevice:: open(OpenMode mode)[virtual]

4)判断是否读到文件末尾

// 判断是否读到文件末尾
// 返回值,true读到文件末尾,反之未读到
bool QFileDevice:: atEnd() const[virtual]

5)读取最大长度为maxSize个的自己到返回值中

// 读取最大长度为maxSize个的自己到返回值中
QByteArray QIODevice:: read(qint64 maxSize)

6)构造一个空字节的字节数组

// 构造函数,QByteArray是Qt中常用的数组
// 构造一个空字节的数组
QByteArray:: QByteArray()

7)向文件流中写数据

// 写出数据
// 参数为写出的内容
// 返回值为实际的数据写出的字节数,出错返回值为-1
qint64 QIODevice:: write(const QByteArray & byteArray)

8)刷新缓冲区

// 刷新缓冲区
bool QFileDevice:: flush()

9)关闭数据流

// 关闭数据流
void QIODevice:: close() [virtual]

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    connect(ui->pushButtonOpen,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));
    connect(ui->pushButtonSave,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));
    connect(ui->pushButtonCopy,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));
}
Dialog::~Dialog()
{
    delete ui;
}
void Dialog::printFileInfo()
{
    //创建文件对象
    QFileInfo fileInfo(readPath);
    if(!fileInfo.exists())
    {
        QMessageBox::warning(this,"提示","无效文件");
        return;
    }
    //获取文件大小
    qint64 fileSize = fileInfo.size();
    QString text = QString::number(fileSize);//int类型转QString类型
    text.prepend("文件大小:").append("字节");//prepend()在text前面插入字符,append()在text后面添加字符
    ui->textBrowserOpen->append(text);
    //获取文件名称
    text = fileInfo.baseName();//前面的text已经打印,重新用只需要覆盖即可。
    text.prepend("文件名称:");
    ui->textBrowserOpen->append(text);
    //获取文件最后修改日期
    text = fileInfo.lastModified().toString("修改日期:yyyy-MM-dd:hh-mm-ss");//获取后直接转为QString类型
    ui->textBrowserOpen->append(text);
    //文件可读性
    bool result = fileInfo.isReadable();//返回值为bool类型
    if(result)
    {
        ui->textBrowserOpen->append("文件可读");
    }
    else
    {
        ui->textBrowserOpen->append("文件不可读");
    }
}void Dialog::copy()
{
    //判断是否有目标文件与路径
    if(readPath == "")
    {
        QMessageBox::warning(this,"提示","请选择要读取的文件");
        return;
    }
    if(writePath == "")
    {
        QMessageBox::warning(this,"提示","请选择要写入的文件路径");
        return;
    }
    //拷贝时屏蔽拷贝按钮
    ui->pushButtonCopy->setEnabled(false);//使能为false
    //创建QFile对象
    QFile readFile(readPath);
    QFile writeFile(writePath);
    //打开文件流
    readFile.open(QIODevice::ReadOnly);//只读模式打开
    writeFile.open(QIODevice::WriteOnly);//只写模式
    //添加进度条效果
    qint64 totalSize = readFile.size();//获取文件总大小
    qint64 hasResd = 0;//已经读写的大小
    QByteArray array;//字节数组类
    //判断是否读到结尾,读到结尾返回true
    while(!readFile.atEnd())
    {
        array = readFile.read(1024);//每次读取1KB
        qint64 writeRet = writeFile.write(array);//返回值为本次写出的大小
        if(writeRet == -1)//如果写出函数的返回值为-1表示写出失败
        {
            QMessageBox::critical(this,"错误","文件拷贝失败");
        }
        //将写出的数据设置给进度条
        hasResd += writeRet;//获取到已经写入总大小
        int per = hasResd*100/totalSize;//计算百分比
        ui->progressBar->setValue(per);//设置给进度条
    }
    //刷新缓冲区
    writeFile.flush();
    //关闭数据流
    readFile.close();
    writeFile.close();
    ui->pushButtonCopy->setEnabled(true);//拷贝完使能true
    //拷贝完成提示
    QMessageBox::information(this,"提示","拷贝完成");
}
void Dialog::btnClickedSlot()
{
    if(ui->pushButtonOpen == sender())
    {
        QString filter = "所有文件(*.*);;Qt(*.cpp *.h *.ui *.pro)";
        QString path = QFileDialog::getOpenFileName(this,"打开","D:/",filter);
        if(path != "")
        {
            ui->textBrowserOpen->append(path);
            readPath = path;
            printFileInfo();
        }
        else if(readPath == "")
        {
            QMessageBox::warning(this,"提示","请选择要打开的文件");
        }
    }
    else if(ui->pushButtonSave == sender())
    {        QString filter = "所有文件(*.*);;Qt(*.cpp *.h *.ui *.pro)";
        QString path = QFileDialog::getSaveFileName(this,"保存","D:/",filter);
        if(path != "")
        {
            ui->textBrowserSave->append(path);
            writePath = path;
        }
        else if(readPath == "")
        {
            QMessageBox::warning(this,"提示","请选择要保存的文件");
        }
    }
    else if(ui->pushButtonCopy == sender())
    {
        copy();
    }
}

使用:先选择原文件路径(打开文件,选择需要拷贝的源文件)。点击保存文件按钮,指定保存文件的路径,及名称(需要加后缀)。点击开始拷贝。

【思考】:上面的代码有问题吗?超大代码拷贝,占用资源,如果执行其他操作时造成指令阻塞。

4、UI与耗时操作

在默认情况下,Qt的项目是单线程的。这个自带的主线程主要用于处理程序的主要任务和UI交互,也被为UI线程。

如果在主线程中实现耗时操作(IO或复杂算法)会导致主线程原本执行的操作被阻塞,甚至无法关闭,形成“假死”的现象。

当操作系统发现某个进行无法正常关闭时,会弹出程序未响应窗口引导用户选择是否强制关闭当前进程。

解决方案是多线程。

5、QThread线程类

5.1 复现程序未响应

QThread类是Qt的线程类,可以使用sleep函数模拟耗时操作。

1)休眠msleep强制线程休眠msecs 个毫秒

// 强制线程休眠msecs 个毫秒 void QThread:: msleep(unsigned long msecs)[static]

#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
    connect(ui->pushButton,SIGNAL(clicked()),
            this,SLOT(btnSleepClickedSlot()));    connect(ui->pushButton_2,SIGNAL(clicked()),
            this,SLOT(close()));
}Dialog::~Dialog()
{
    delete ui;
}void Dialog::btnSleepClickedSlot()
{
    qDebug() << "睡眠开始";
    QThread::msleep(15000);
    qDebug() << "睡眠结束";
}

5.2 创建并启动一个子线程

主线程以外的所有线程都是子线程。子线程不能执行主线程的UI操作,只能指向耗时操作。(不要用栈区创建线程)

创建并启动一个自定义的子线程步骤:

  1. 在Qt Creator中选中项目名称,鼠标右键,点击“添加新文件
  2. 在弹出的窗口中,先设置类名,然后再选择基类名称QObject,最后点击“下一步”:

3、在项目管理界面,直接点击完成,可以看到线程类的文件已经创建。

  1. 选择新建的头文件,把继承的QObject更改为QThread。

  1. 选择新建的.cpp文件,把透传构造的QObject更改为QThread。

  1. run函数,在自定义线程中,覆盖基类中QThread的run函数。

此函数是子线程执行的起始点,也是子线程的结束点

// 此函数是子线程执行的起始点,也是子线程的结束点
void QThread:: run() [virtual][protected]

7、创建自定义子线程对象,并调用start函数启动子线程

// 启动子线程,调用此函数后,会在子线程中执行run函数。
// 参数为子线程执行的优先级,默认值为创建时所在的线程相同优先级
void QThread:: start(Priority priority = InheritPriority)

mythread.h/.cpp

dialog.h/.cpp

5.3 异步刷新

在实际开发中,两个线程不可能毫无关系的前提下各干各的,最常见的情况是主线程分配一个耗时任务给子线程,子线程需要把耗时任务的执行的执行情况反馈给主线程。主线程刷新子线程耗时操作,并展示对应的UI效果。

【例子】:子线程执行文件拷贝,主线程显示拷贝的进度。

通常子线程是主线程对象的子对象,因此异步通信刷新就是对象通信问题,使用信号槽解决。

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{
    ui->setupUi(this);connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(btnSleepClickedSlot()));}Dialog::~Dialog()
{delete ui;
}void Dialog::btnSleepClickedSlot()
{
    ui->pushButton->setEnabled(false);// 创建子线程对象并启动
    MyThread *mt = new MyThread(this);connect(mt,SIGNAL(valueSignal(int)),this,SLOT(valueSlot(int)));
    mt->start();
}void Dialog::valueSlot(int value)
{
    ui->progressBar->setValue(value);if(value == 100){
        ui->pushButton->setEnabled(true);this->hide();   // 隐藏主窗口this->show();QMessageBox::information(this,"通知","拷贝完成");}
}

myThread.cpp

#include "mythread.h"MyThread::MyThread(QObject *parent) : QThread(parent)
{}MyThread::~MyThread()
{
}void MyThread::run()
{for(int i = 0;<= 100;i++){QThread::msleep(100);
        emit valueSignal(i);}
}

练习:线程对象构造函数传参

子线程执行文件拷贝,主线程显示拷贝的进度。注:真正的文件拷贝。

线程传参.h

线程传参.cpp构造函数

创建子线程对象传参

方法二:成员函数构造调用传参

成员函数构造

成员函数构造调用传参

5.4 线程停止

子线程往往执行耗时操作,耗时操作又往往伴随着循环,因此并不建议使用粗暴的方式直接停止线程,因为强行停止线程会导致耗时资源无法回收等问题。

可以通过给循环设置标志位的方式使线程停止。

dialog.cpp

#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);      connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(btnSleepClickedSlot()));
}
Dialog::~Dialog()
{
    delete ui;
}
void Dialog::btnSleepClickedSlot()
{
    if(ui->pushButton->text() == "开始拷贝")
    {
    //创建子线程对象并启动
    mt = new myThread(this);
    connect(mt,SIGNAL(valueSignal(int)),this,SLOT(valueSlot(int)));
    mt->setRuningState(true);
    mt->start();
    ui->pushButton->setText("停止拷贝");
    }
    else if(ui->pushButton->text() == "停止拷贝")
    {
        ui->pushButton->setText("开始拷贝");
        mt->setRuningState(false);
    }
}
void Dialog::valueSlot(int value)
{
    ui->progressBar->setValue(value);
    if(value == 100)
    {
        ui->pushButton->setEnabled(true);
        this->hide();//隐藏主窗口,让出焦点
        this->show();
        QMessageBox::information(this,"通知","拷贝完成");
    }
}

mythread.cpp                                              

#include "mythread.h"
myThread::myThread(QObject *parent) : QThread(parent)
{
}
myThread::~myThread()
{
}
bool myThread::getRuningState() const
{
    return runingState;
}
void myThread::setRuningState(bool value)
{
    runingState = value;
}
void myThread::run()
{
    for(int i= 0;i<=100 && runingState;i++)
    {
        QThread::msleep(100);
        emit valueSignal(i);
    }
    qDebug()<<"释放资源成功";
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/641890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity3D控制人物移动的多种方法

系列文章目录 unity知识点 文章目录 系列文章目录前言一、人物移动之键盘移动1-1、代码如下1-2、效果 二、人物移动之跟随鼠标点击移动2-1、代码如下2-2、效果 三、人物移动之刚体移动3-1、代码如下3-2、效果 四、人物移动之第一人称控制器移动4-1、代码如下4-2、效果 五、And…

从编程中思考:大脑的局部与全局模式(一)

郭靖正在帐篷中用Unity写代码&#xff0c;刚写完一段代码。欧阳锋从帐篷外走进来&#xff0c;正要说点什么&#xff0c;郭靖反应敏捷&#xff0c;转身反手一招神龙摆尾击出&#xff0c;将欧阳锋震出帐篷&#xff0c;灰溜溜逃跑。 using UnityEngine;public class LocalGlobalD…

Maven 综合案例

1. 项目需求和结构分析 需求案例&#xff1a;搭建一个电商平台项目&#xff0c;该平台包括用户服务、订单服务、通用工具模块等。 项目架构&#xff1a; 用户服务&#xff1a;负责处理用户相关的逻辑&#xff0c;例如用户信息的管理、用户注册、登录等。 spring-context 6.0.…

P1320 压缩技术(续集版)(C语言)

基本思路是&#xff1a; 1.读入字符串并计算n值 2.字符串连接&#xff08;要用到strcat&#xff09; 3.输出n值 4.计算字符数并输出 其中输出时第一个数字是0的个数&#xff0c;这个很容易被遗漏。 #include<stdio.h> #include<string.h> int main() {char a[…

centos 7.6 进入单用户模式

1、重启服务器&#xff0c;在选择内核界面使用上下箭头移动 2、选择内核并按“e” 将“RO”改成 rw ,删除 rhgb quiet 添加 init/bin/bash Ctrl X 进入单用户模式 为防止乱码&#xff0c;修改语言为英语 修改完密码建议输入&#xff1a;touch /.autorelabel 更新系统信…

imgaug库图像增强指南(34):揭秘【iaa.Clouds】——打造梦幻般的云朵效果

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

mysql 导入数据 1273 - Unknown collation: ‘utf8mb4_0900_ai_ci‘

前言: mysql 导入数据 遇到这个错误 1273 - Unknown collation: utf8mb4_0900_ai_ci 具体原因没有深究 但应该是设计数据库的 字符集类型会出现这个问题 例如: char varchar text..... utf8mb4 类型可以存储表情 在现在这个时代会用很多 以后会用的更多 所以不建议改…

SV-7101V网络音频终端产品简介

SV-7101V网络音频终端产品简介 网络广播终端SV-7101V&#xff0c;接收网络音频流&#xff0c;实时解码播放。本设备只有网络广播功能&#xff0c;是一款简单的网络广播终端。提供一路线路输出接功放或有源音箱。18123651365微信 产品特点 ■ 提供固件网络远程升级■ 标准RJ…

CSS之边框样式

让我为大家介绍一下边框样式吧&#xff01;如果大家想更进一步了解边框的使用&#xff0c;可以阅读这一篇文章&#xff1a;CSS边框border 属性描述none没有边框,即忽略所有边框的宽度(默认值)solid边框为单实线dashed边框为虚线dotted边框为点线double边框为双实线 代码演示&…

教你怎么用Docker 部署前端

越来越多的前端团队选择用 Docker 部署前端项目&#xff0c;方法是将项目打包成一个镜像&#xff0c;然后在服务端直接拉镜像启动项目。这种方式可以忽略服务器环境差异&#xff0c;更容易做版本管理。 但我们平常使用 Docker 拉取镜像时&#xff0c;默认会从 Docker Hub 这个…

PWM调光 降压恒流LED芯片FP7127:为照明系统注入新能量(台灯、GBR、调光电源、汽车大灯)

目录 一、降压恒流LED芯片FP7127 二、降压恒流LED芯片FP7127具有以下特点&#xff1a; 三、降压恒流LED芯片FP7127应用领域&#xff1a; LED照明和调光的新纪元随着LED照明技术的不断发展&#xff0c;人们对于照明调光的需求也越来越高。PWM调光技术作为一种常用的调光方法&…

一、认识 JVM 规范(JVM 概述、字节码指令集、Class文件解析、ASM)

1. JVM 概述 JVM&#xff1a;Java Virtual Machine&#xff0c;也就是 Java 虚拟机 所谓虚拟机是指&#xff1a;通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的计算机系统。 即&#xff1a;虚拟机是一个计算机系统。这种计算机系统运行在完全隔离的环境中…

【心得】java反序列化漏洞利用启蒙个人笔记

目录 前置基础概念 java的反序列化利用概念baby题 例题1 例题2 java反序列化启蒙小结&#xff1a; URLDNS链 一句话总结&#xff1a; 简单分析&#xff1a; 利用点&#xff1a; 示例&#xff1a; 前置基础概念 序列化 类实例->字节流 反序列化 字节流->类实…

卡尔曼滤波器原理By_DR_CAN 学习笔记

DR_CAN卡尔曼滤波器 Kalman Filter Recursive Algorithm迭代过程 数学基础正态分布和6-SigmaData FusionCovariance MatrixState Space Representation离散化推导 linearizationTaylor Series2-DSummary Step by Step Derivation of Kalman Gain矩阵求导公式 Prior / Posterio…

如何在Docker上运行Redis

环境: 1.windows系统下的Docker deckstop 1.Pull Redis镜像 2.运行Redis镜像 此时,Redis已经启动&#xff0c;我们登录IDEA查看下是否连接上了 显示连接成功&#xff0c;证明已经连接上Docker上的Redis了

积分梳状滤波器CIC原理与实现

CIC&#xff08;Cascade Intergrator Comb&#xff09;&#xff1a;级联积分梳状滤波器&#xff0c;是由积分器和梳状滤波器级联而得。滤波器系数为1&#xff0c;无需对系数进行存储&#xff0c;只有加法器、积分器和寄存器&#xff0c;资源消耗少&#xff0c;运算速率高&#…

如何基于 ESP32 芯片测试 WiFi 连接距离、获取连接的 AP 信号强度(RSSI)以及 WiFi吞吐测试

测试说明&#xff1a; 测试 WiFi 连接距离&#xff0c;是将 ESP32 作为 WiFi Station 模式来连接路由器&#xff0c;通过在开阔环境下进行拉距来测试。另外&#xff0c;可以通过增大 WiFi TX Power 来增大连接距离。 获取连接的 AP 信号强度&#xff0c;一般可以通过 WiFi 扫描…

Java应用崩溃的排查流程

目录 分析问题 hs_err_pid.log 上周排查了一个java应用的崩溃问题&#xff0c;在这里记录一下。 分析问题 首先是排查到/tmp目录下有很多的core文件&#xff0c;形式类似&#xff1a; core-18238-java-1705462412 1.3 GB 程序崩溃数据 2024-01-17 11:33:44 core-18108…

Leetcode28-合并相似的物品(2363)

1、题目 给你两个二维整数数组 items1 和 items2 &#xff0c;表示两个物品集合。每个数组 items 有以下特质&#xff1a; items[i] [valuei, weighti] 其中 valuei 表示第 i 件物品的 价值 &#xff0c;weighti 表示第 i 件物品的 重量 。 items 中每件物品的价值都是 唯一…

语义分割常用评价指标

在图像处理领域中&#xff0c;语义分割是很重要的一个任务。在实际项目开发中,评估模型预测效果以及各指标的含义对于优化模型极为重要。 本文将主要评价指标的计算算法进行了详细说明,并加上注释解释每个指标的含义。这对理解各指标背后的数学原理以及能否在实践中应用或许有…