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()<<"释放资源成功";
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux:动静态库的概念制作和底层工作原理

文章目录 动静态库基础认知动静态库基本概念静态库的制作库的概念包的概念 静态库的使用第三方库小结 动态库的制作动态库的使用动态库如何找到内容&#xff1f;小结 动态库加载库和程序都要加载可执行程序的地址问题地址问题逻辑地址和平坦模式绝对编址和相对编址与位置无关码…

esxi配置NTP自动对时与手动对时

目录 背景解法配置NTP服务器立即与NTP服务器同步时间 附&#xff1a;几个常用的NTP服务器列表 背景 VMware ESXi 6.7运行了一段时间后偶然发现系统时间与标准时间有5分钟左右的差异&#xff0c;于是研究了下如何自动对时以及用命令行立即对时。 解法 配置NTP服务器 首先在管…

啥,ui叫我做一个移动端好看的轮播--异形的Slide

先看效果,得实现两边的缩放和无线滚动 实现方法 我的基础架构是 next.jsswiper 下载swiper包 yarn add swiper下载后在页面中引用 import { useEffect, useState } from "react"; import styles from "./index.module.css"; import Image from "n…

DataStream API(源算子)

目录 源算子 1&#xff0c;从集合中读取数据 2&#xff0c;从文件读取数据 3&#xff0c;从 Socket 读取数据 4&#xff0c;从 Kafka 读取数据 5&#xff0c;自定义源算子 6&#xff0c;Flink 支持的数据类型 6.1 Flink 支持多种数据类型&#xff0c;包括但不限于&…

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

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

Linux Centos7环境下安装Redis5

Centos7环境下安装Redis5 使用 yum 安装创建符号链接针对可执⾏程序设置符号链接针对配置⽂件设置符号链接 修改配置文件启动Redis停止Redis 一般情况下我们在 linux 系统中想要安装一些程序首先会想到使用 yum 源来安装, 但是在下图中我们可以看到 Redis 版本还是3.X的版本, 所…

优化用户体验测试应用领域:提升产品质量与用户满意度

在当今数字化时代&#xff0c;用户体验测试应用已经成为确保产品质量、提升用户满意度的关键工具。随着技术的不断发展&#xff0c;用户的期望也在不断演变&#xff0c;因此&#xff0c;为了保持竞争力&#xff0c;企业必须将用户体验置于产品开发的核心位置。本文将探讨用户体…

vcruntime140_1.dll文件丢失有什么办法可以解决

vcruntime140_1.dll文件丢失是电脑中常见的事情&#xff0c;解决vcruntime140_1.dll丢失的办法也有很多种&#xff0c;今天我们就来聊聊为什么要修复vcruntime140_1.dll文件&#xff0c;vcruntime140_1.dll在电脑中的重要性&#xff0c;以及详细的解决vcruntime140_1.dll丢失的…

GPT-5不叫GPT-5?下一代模型会有哪些新功能?

OpenAI首席执行官奥特曼在上周三达沃斯论坛接受媒体采访时表示&#xff0c;他现在的首要任务就是推出下一代大模型&#xff0c;这款模型不一定会命名GPT-5。虽然GPT-5的商标早已经注册。 如果GPT-4目前解决了人类任务的10%&#xff0c;GPT-5应该是15%或者20%。 OpenAI从去年开…

使用DockerFile构建镜像与镜像上传

目录 前言&#xff1a;为什么要使用Dockerfile &#xff1f; DockerFile构建镜像 1、构建基础对象 2、Dockerfile文件结构 3、构建Dockerfile文件镜像 二、镜像上传&#xff08;阿里云&#xff09; 前言&#xff1a;为什么要使用Dockerfile &#xff1f; 首先Dockerfile …

Element组件完整引入、按需引入、样式修改(全局、局部)、简单安装less以及npm命令证书过期等

目录 一、npm 安装二、完整引入三、按需引入四、样式修改1.按需加载的全局样式修改2. 局部样式修改1. 在 css 预处理器如 less scss 等直接使用::v-deep2. 只能用在原生 CSS 语法中:/deep/ 或者 >>> 五、 拓展&#xff1a;npm 安装less报错&#xff0c;提示证书过期六…

Java Web(二)--HTML

基本介绍 官网文档地址: HTML 教程 HTML&#xff08;HyperText Mark-up Language&#xff09;即超文本标签语言&#xff1b;HTML 文本是由 HTML 标签组成的文本&#xff0c;可以包括文字、图形、动画、声音、表格、链接等&#xff1b;HTML 的结构包括头部&#xff08;Head&…

CWE、CVE

文章目录 前言一、CVE是什么&#xff1f;二、官网浏览主页词汇 三、CWE 前言 一、CVE是什么&#xff1f; 关于CVE是什么&#xff0c;前辈已经阐述得很详细通透&#xff0c;这里不再赘述或生产一些垃圾信息&#xff0c;CVE公共漏洞和暴露的学习 总结&#xff1a; 标识某个漏洞…

不就业,纯兴趣,应该自学C#还是JAVA?

不就业&#xff0c;纯兴趣&#xff0c;应该自学C#还是JAVA? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「JAVA的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff…

测试老司机聊聊测试设计都包含什么?

一、数据组合测试设计 数据组合测试设计&#xff08;Combinatorial Test Design&#xff0c;CTD&#xff09;是一种优化测试用例的方法&#xff0c;它通过系统地组合不同的测试数据输入&#xff0c;以确保全面覆盖各种可能的测试情况。这种方法主要应用于软件测试领域&#xff…

Aria2 WebUI控制台 任意文件读取漏洞复现(CVE-2023-39141)

0x01 产品简介 Aria2 WebUI控制台是用于下载文件的实用程序。它支持 HTTP(S)/FTP/SFTP/BitTorrent 和 Metalink 协议。aria2可以从多个来源/协议下载文件,并尝试利用您的最大下载带宽。它支持同时从HTTP(S)/FTP/SFTP和BitTorrent下载文件,而从HTTP(S)/FTP/SFTP下载的数据上…

【算法】选择最佳路线(超级源点)

题目 有一天&#xff0c;琪琪想乘坐公交车去拜访她的一位朋友。 由于琪琪非常容易晕车&#xff0c;所以她想尽快到达朋友家。 现在给定你一张城市交通路线图&#xff0c;上面包含城市的公交站台以及公交线路的具体分布。 已知城市中共包含 n 个车站&#xff08;编号1~n&…

银行数据仓库体系实践(4)--数据抽取和加载

1、ETL和ELT ETL是Extract、Transfrom、Load即抽取、转换、加载三个英文单词首字母的集合&#xff1a; E&#xff1a;抽取&#xff0c;从源系统(Souce)获取数据&#xff1b; T&#xff1a;转换&#xff0c;将源系统获取的数据进行处理加工&#xff0c;比如数据格式转化、数据精…

原来岳云鹏背后的女人竟然是她?有她,岳云鹏红遍大江南北。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 岳云鹏&#xff0c;一个出身于农村的普通孩子&#xff0c;曾经…

如何在容器内部进行抓包

//先获取POD 的容器ID号 //去pod容器所在节点进行解析id为pid号 //通过pid号进入这个容器的网络命名空间 docker inspect --format {{.State.Pid}} 05f38d2a61e29b5a9d24fc7a3906991ab92ecd58ff7e0eb4e339a4cc6b2c4fc4 //访问容器内部&#xff0c;Node01节点