【Qt之·文件操作·类QTextStream、QDataStream】

news2024/11/15 11:32:50

系列文章目录


文章目录

  • 前言
  • 一、概述
    • 1.1 QTextStream类
    • 1.2 QTextStream类的作用和用途
  • 二、基本用法
    • 2.1 QTextStream成员函数
    • 2.2 QTextStream格式描述符、描述符方法
    • 2.3 QDataStream成员函数
    • 2.4 创建QTextStream对象并关联输入/输出设备(如文件、标准输入/输出流等)
    • 2.5 读取和写入字符串
  • 三、QTextStream的输入操作
    • 3.1 从文件读取数据
    • 3.2 从字符串读取数据
    • 3.3 从标准输入读取数据
  • 四、QTextStream的输出操作
    • 4.1 向文件写入数据
    • 4.2 向字符串写入数据
    • 4.3 向标准输出写入数据
  • 五、QTextStream的输入输出格式设置
    • 5.1 设置数值的精度
    • 5.2 设置字段宽度
    • 5.3 设置填充字符
    • 5.4 设置文本对齐方式
    • 5.5 设置字符串宽度
  • 六、QTextStream的更高级用法
    • 6.1 设置流的编码格式
    • 6.2 QIODevice的数据流与QTextStream的关系
  • 七、QTextStream的错误处理
    • 7.1 如何使用QTextStream类处理文本输入输出时可能出现的错误
    • 7.2 QTextStream类提供的错误处理函数和错误状态。
  • 八、实例演示
  • 总结


前言

  QTextStream类是Qt框架中用于读写文本的类。它可以方便地读取和写入各种类型的数据,如字符串、整数、浮点数等。QTextStream类可以与文件、字符串、标准输入输出设备等进行交互,并且支持读取和写入不同的编码格式。


一、概述

1.1 QTextStream类

  QTextStream类是Qt中的一个用于读写文本数据的工具类。 它提供了简单而方便的接口,可以以流的方式读取和写入文本数据。QTextStream可以与任何QIODevice(如文件、套接字、字符串等)一起使用,并支持不同的编码格式。

使用QTextStream可以实现文本文件的读取和写入,也可以将文本数据插入到字符串中,或者从字符串中读取文本数据。它还提供了一些方便的方法,可以按行读取和写入文本数据,或者将文本数据按照指定的分隔符进行分割和合并。

QTextStream类是Qt的IO模块中的一部分,它被广泛用于Qt应用程序中进行文本数据的处理和操作。

1.2 QTextStream类的作用和用途

  • 读取和写入文本文件: 可以使用QTextStream读取和写入文本文件,支持不同的编码格式。通过使用QFile或QIODevice来打开文件,并将其传递给QTextStream,可以轻松地读取和写入文本文件的内容。

  • 字符串的读写: QTextStream可以将字符数据读取到字符串中,也可以将字符串写入到流中。这对于处理内存中的字符串数据非常有用,可以在内存中进行文本操作而不用进行实际的文件读写。

  • 流式操作: QTextStream提供了方便的流式操作,可以按照特定的分隔符将文本数据分割成单独的部分,或者将多个部分合并成一个字符串。这对于解析和拼接文本数据非常有用。

  • 行操作: QTextStream提供了逐行读取和写入文本数据的方法,方便处理大型的文本文件。可以使用readLine()方法逐行读取文件,或者使用writeLine()方法将字符串以行的形式写入文件。

  • 格式化输出: QTextStream提供了方便的格式化输出功能,可以将不同类型的数据格式化为字符串并写入流中。例如,可以使用<<操作符将整数、浮点数等数据直接写入流中,而无需手动转换为字符串。

二、基本用法

2.1 QTextStream成员函数

函数描述
bool QTextStream::atEnd() const判断是否读到文件末尾,如果已经达到末尾,返回 true,否则返回 false。
QString QTextStream::read(qint64 maxlen)从文件中读最多 maxlen 个字符,返回这些字符组成的 QString 字符串。
QString QTextStream::readAll()从文件中读取所有内容,返回由读取内容组成的 QString 字符串。
QString QTextStream::readLine(qint64 maxlen = 0)默认读取一行文本,如果手动指定 maxlen 的值,则最多读取 maxlen 个字符,并返回读取内容组成的 QString 字符串。
void QTextStream::setFieldAlignment(FieldAlignment mode)设置对齐方式,通常与 setFieldWidth() 一起使用。
void QTextStream::setFieldWidth(int width)设置每份数据占用的位置宽度为 width。

2.2 QTextStream格式描述符、描述符方法

枚举值函数描述
Qt::hexQTextStream::setIntegerBase(16)将指定整数对应的 16 进制数写入到文件中。
Qt::showbaseQTextStream::setNumberFlags(numberFlags()ShowBase) 对于非十进制数,写入到文件中时带上相应的前缀。二进制数前缀是 0b,八进制数前缀是 0,十六进制数前缀是 0x。
Qt::forcesignQTextStream::setNumberFlags(numberFlags()ForceSign) 将数字写入文件时,带上正负号。
Qt::fixedQTextStream::setRealNumberNotation(FixedNotation)将浮点数以普通小数的形式写入文件。
Qt::scientificQTextStream::setRealNumberNotation(ScientificNotation)将浮点数以科学计数法的形式写入文件。
Qt::leftQTextStream::setFieldAlignment(AlignLeft)左对齐
Qt::rightQTextStream::setFieldAlignment(AlignRight)右对齐
Qt::centerQTextStream::setFieldAlignment(AlignCenter)居中对齐

2.3 QDataStream成员函数

函数描述
bool QDataStream::atEnd() const判断是否读到文件末尾,如果已经达到末尾,返回 true,否则返回 false
QDataStream &QDataStream::readBytes(char *&s, uint &l)对于用 writeBytes() 方法写入文件的 l 和 s,只能使用 readBytes() 方法读取出来
int QDataStream::readRawData(char *s, int len)从文件中读取最多 len 字节的数据到 s 中,返回值表示实际读取的字节数。注意,调用该方法之前,需要先给 s 参数分配好内存空间
void QDataStream::setVersion(int v)不同版本的 Qt 中,同名称的数据类型也可能存在差异,通过调用此方法手动指定版本号,可以确保读取数据的一致性
int QDataStream::skipRawData(int len)跳过文件中的 len 个字节,返回实际跳过的字节数
QDataStream &QDataStream::writeBytes(const char *s, uint len)将长度 len 和 s 一起写入到文件中,对于 writeBytes() 写入的数据,只能用 readBytes() 方法读取
int QDataStream::writeRawData(const char *s, int len)将 s 中前 len 字节的数据写入文件,返回值表示成功写入的字节数

2.4 创建QTextStream对象并关联输入/输出设备(如文件、标准输入/输出流等)

// 1. 关联标准输入设备(stdin)
QTextStream in(stdin);

// 2. 关联标准输出设备(stdout)
QTextStream out(stdout);

// 3. 关联文件读取设备
QFile file("input.txt");
if (file.open(QIODevice::ReadOnly)) {
    QTextStream in(&file);
}

// 4. 关联文件写入设备
QFile file("output.txt");
if (file.open(QIODevice::WriteOnly)) {
    QTextStream out(&file);
}

// 5. 关联字节数组设备
QByteArray byteArray;
QTextStream stream(&byteArray);

// 6. 关联字符串设备
QString string;
QTextStream stream(&string);

2.5 读取和写入字符串

QString str = "Hello, World!";

// 写入字符串到QTextStream
QTextStream out(stdout);
out << str << endl;

// 读取字符串从QTextStream
QTextStream in("Hello, World!");
QString readStr;
in >> readStr;

qDebug() << "Read string: " << readStr;

运行结果

Hello, World!
Read string:  "Hello,"

注意: QTextStream在读取字符串时,默认情况下会根据空格或换行符作为分隔符。因此,在上述示例中,只读取了"Hello,“而不是整个字符串"Hello, World!”。要读取整个字符串,请使用QString的全读取函数:readAll()。

三、QTextStream的输入操作

3.1 从文件读取数据

QFile file("example.txt");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    QTextStream in(&file);
    QString line;
    while (!in.atEnd()) {
        line = in.readLine();
        // 处理每一行数据
        qDebug() << line;
    }
    file.close();
} else {
    qDebug() << "Failed to open file.";
}

3.2 从字符串读取数据

QString str = "Hello, World!";
QTextStream in(&str);
QString word;
while (!in.atEnd()) {
    in >> word;
    // 处理每一个单词
    qDebug() << word;
}

3.3 从标准输入读取数据

QTextStream in(stdin);
QString word;
while (!in.atEnd()) {
    in >> word;
    // 处理每一个单词
    qDebug() << word;
}

四、QTextStream的输出操作

4.1 向文件写入数据

QFile file("data.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
    QTextStream out(&file);
    out << "Hello, World!" << endl;
    out << "This is a sample text." << endl;
    // 写入其他数据
    file.close();
}

4.2 向字符串写入数据

QString data;  // 声明一个空字符串

QTextStream stream(&data);  // 创建一个QTextStream对象,并将其与字符串关联起来

stream << "Hello, World!" << endl;  // 向字符串中写入数据
stream << "This is a sample text." << endl;

// 输出字符串中的数据
qDebug() << data;  // 或者使用cout打印到控制台

4.3 向标准输出写入数据

QTextStream out(stdout); // 创建一个QTextStream对象,将其与标准输出关联
out << "Hello, World!" << endl; // 使用<<运算符将数据写入QTextStream对象

五、QTextStream的输入输出格式设置

5.1 设置数值的精度

QTextStream out(stdout);
out.setRealNumberPrecision(2);
double num = 3.14159;
out << "Number: " << num << endl;  // 输出 Number: 3.14

5.2 设置字段宽度

QTextStream out(stdout);
out.setFieldWidth(8);
int num = 42;
out << "Number: " << num << endl;  // 输出 Number:       42

5.3 设置填充字符

QTextStream out(stdout);
out.setFieldWidth(8);
out.setPadChar('*');
int num = 42;
out << "Number: " << num << endl;  // 输出 Number: *****42

5.4 设置文本对齐方式

QTextStream out(stdout);
out.setFieldAlignment(QTextStream::AlignRight);
int num = 42;
out << "Number: " << num << endl;  // 输出 Number:       42

5.5 设置字符串宽度

QTextStream out(stdout);
out.setString(&str);  // str 是一个QString对象
out.setFieldWidth(8);
out << "Text: " << "hello" << endl;  // 输出 Text:    hello

六、QTextStream的更高级用法

6.1 设置流的编码格式

在使用QTextStream对象时,可以通过setCodec()函数设置流的编码格式。下面是一些示例:

设置输出流的编码格式为UTF-8:

QFile file("output.txt");
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
    QTextStream out(&file);
    out.setCodec("UTF-8");
    out << "中文" << endl;  // 输出中文到文件中
    file.close();
}

设置输入流的编码格式为GBK:

QFile file("input.txt");
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    QTextStream in(&file);
    in.setCodec("GBK");
    QString str = in.readAll();  // 读取文件的内容
    file.close();
}

在设置编码格式时,可以使用Qt支持的任何编码格式,例如"UTF-8"、“GBK”、"ISO-8859-1"等。如果不设置编码格式,默认情况下Qt会使用系统的默认编码格式。

注意: 设置编码格式仅适用于文本流的读取和写入操作,对于二进制数据的读取和写入无效。对于二进制数据的读取和写入操作,应该使用QDataStream对象。

6.2 QIODevice的数据流与QTextStream的关系

QIODevice是Qt中用于读写数据的设备的基类,它提供了一种通用的接口,可以用于访问各种不同类型的设备,如文件、网络套接字等。QIODevice可以用于读取和写入原始数据,但对于文本数据的读写,可以使用QTextStream类。

QTextStream是对QIODevice进行了封装的类,它提供了一种方便的方式来读写文本数据。通过QTextStream,可以以文本方式读取和写入QIODevice对象中的数据。QTextStream提供了方便的函数和操作符重载,用于读写各种数据类型,如QString、QChar、int等。

使用QTextStream可以对QIODevice进行文本读写操作,但需要注意的是,如果对QIODevice进行了原始二进制数据的读写操作,那么QTextStream可能会导致数据的丢失或损坏。因此,在读写二进制数据时,应该使用QDataStream类进行操作。

总结起来,QIODevice是Qt中用于读写数据的设备的基类,而QTextStream是对QIODevice进行了文本读写操作的封装类。在处理文本数据时,可以使用QTextStream来简化操作;在处理二进制数据时,应该使用QDataStream来确保数据的完整性。

七、QTextStream的错误处理

7.1 如何使用QTextStream类处理文本输入输出时可能出现的错误

以下是一些常见的错误类型及其解决方法:

打开文件错误: 在使用QTextStream读取或写入文件时,可能会遇到无法打开文件的情况。这可能是因为文件不存在、无权限或者文件路径错误。在打开文件之前,应该确保文件存在,并且具有适当的权限。可以使用QFile的exists()函数检查文件是否存在,并使用QFile的error()函数获取错误信息。
 
读取或写入格式错误: 在使用QTextStream读取或写入数据时,可能会遇到格式不匹配或解析错误的情况。这可能是因为读取或写入操作与文件内容的格式不一致。在读取数据时,可以使用QTextStream的atEnd()函数检查是否已经读取完整个文件。在写入数据时,可以使用QTextStream的status()函数检查写入的状态。
 
编码问题: 在读取或写入文本时,可能会遇到编码不匹配的问题。这可能导致文本的乱码或无法正确解析。在使用QTextStream读取或写入数据时,应该确保使用与文件或流相同的编码。可以使用QTextStream的setCodec()函数设置编码。另外,可以使用QTextCodec类来进行编码转换。
 
** 写入缓冲问题:** 在使用QTextStream写入数据时,可能会遇到缓冲区问题。QTextStream使用缓冲区来提高性能,但在某些情况下,可能需要手动刷新缓冲区。可以使用QTextStream的flush()函数手动刷新缓冲区,以确保数据被写入文件。
 
异常处理: 在使用QTextStream进行文本输入输出时,还应该考虑到可能发生的异常情况。可以使用try-catch语句块来捕捉并处理可能发生的异常,以确保程序能够正确处理错误。

7.2 QTextStream类提供的错误处理函数和错误状态。

函数描述
QTextStream::status()该函数返回当前文本流的状态,以QTextStream::Status枚举值表示。常见的状态值包括Ok(无错误)、ReadPastEnd(读取到文件末尾)、ReadCorruptData(读取到损坏的数据)等。可以通过此函数获取当前文本流的状态。
QTextStream::setCodec(const QTextCodec *codec)该函数设置文本流的编码方式。错误的编码方式可能导致读取或写入操作失败,无法解析或显示正确的文本。通过设置正确的编码方式,可以避免编码错误导致的异常。
QTextStream::setErrorString(const QString &errorString)该函数用于设置错误信息字符串,以便在出现错误时使用。通过setErrorString()函数设置错误信息,可以在发生错误时获取详细的错误描述。
QTextStream::readLine()该函数用于按行读取文本。如果读取到文件末尾或发生错误,函数将返回一个空的QString。
QTextStream::atEnd()该函数用于检查是否已经读取到文本流的末尾。如果已经读取完全部的数据,函数将返回true;否则返回false。
QTextStream::flush()该函数用于刷新文本流的缓冲区,确保数据被写入文件。在写入大量数据时,为了提高性能,QTextStream会将数据存储在内部的缓冲区中。通过调用flush()函数,可以强制将缓冲区中的数据写入到文件中。。

八、实例演示

示例1:

QTextStream out(stdout);

//    out.setFieldWidth(15);
    out.setPadChar('%');
    out << "Hello World!\n";
    out.setFieldAlignment(QTextStream::AlignLeft);
    out << "Hello World!\n";
    out << "Hello World!\n";
    out << QString("中文\n");
    out.setCodec("GBK"); //影响全局输出
    out << QString::fromLocal8Bit("中文\n");

运行结果:
在这里插入图片描述


总结

QTextStream的主要特点如下:

支持不同的数据源: QTextStream可以读取和写入不同的数据源,包括文件、字符串和标准输入输出设备等。
 
支持不同的文本编码: QTextStream可以根据需要使用不同的文本编码,包括ASCII、UTF-8和UTF-16等。
 
容易使用: QTextStream提供了一系列的操作符重载,使得读写操作更加方便。例如,可以使用“<<”操作符将数据写入到文本流中,使用“>>”操作符从文本流中读取数据。
 
自动管理文本编码和格式: QTextStream会自动处理不同的文本编码和格式。例如,当写入文本数据时,它会根据文本编码自动进行转换;当读取文本数据时,它会自动跳过空格和换行符等。
 
支持流定向: 可以通过设置设备为只读或只写模式来限制读写操作。此外,还可以设置设备的偏移量,以便在读写操作中定位到特定的位置。

QTextStream的主要用法如下:

创建QTextStream对象: 可以通过传入一个设备对象(如QFile或QIODevice)来创建一个QTextStream对象。
 
读取数据: 可以使用“>>”操作符来从文本流中读取数据。例如,可以使用“stream >> data;”将数据从文本流中读取到变量data中。
 
写入数据: 可以使用“<<”操作符将数据写入到文本流中。例如,可以使用“stream << data;”将变量data中的数据写入到文本流中。
 
设置文本编码和格式: 可以使用setCodec()方法设置文本编码,使用setFieldWidth()和setPadChar()方法设置文本字段宽度和填充字符等。
 
定位和偏移: 可以使用seek()方法在读写操作中定位到特定的位置,使用pos()方法获取当前的偏移量。
 
错误处理: 可以使用status()方法检查读写操作的状态,使用setErrorString()方法设置错误信息。

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

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

相关文章

EPSILON环境配置和本地测试

文章目录 一、环境配置1.1 拉取镜像构建容器1.2 在容器中安装常用的包1.3 安装依赖1.4 安装OOQP1.4.1 安装blas1.4.2 安装ma271.4.3 安装OOQP 1.5 安装Protobuf 二、本地编译测试2.1 拉取源码并编译2.2 X11转发docker图形化界面2.3 测试一个小例子 三、镜像 一、环境配置 宿主…

Vue3:$attrs实现组件通信

目录 一.性质 1.响应式 2.包含所有非prop属性 3.动态属性 二.作用 1.访问非prop属性 2.灵活性 3.组件重用 三.使用 1.爷爷组件 2.父亲组件 3.儿子组件 四.代码 1.爷爷组件代码 2.父亲组件代码 3.孙子组件代码 五.效果图 在Vue 3中&#xff0c;$attrs 是一个响…

string类的模拟实现以及oj题

前言 上篇博客实现了string类的begin()、end()、构造函数、析构函数、c_str、size()、clear()、capacity()、[ ]、reserve()、push_back、append()、insert()、。这篇博客实现剩下的一些重要功能。 string类的模拟实现 string.h #include<iostream> #include<stri…

稳了,搭建Docker国内源图文教程

大家好&#xff0c;之前分享了我的开源作品 Cloudflare Workers Proxy&#xff0c;它的作用是代理被屏蔽的地址&#xff0c;理论上支持代理任何被屏蔽的域名&#xff0c;使用方式也很简单&#xff0c;只需要设置环境变量 PROXY_HOSTNAME 为被屏蔽的域名&#xff0c;最后通过你的…

强化信息安全:密码机密钥管理的策略与实践

强化信息安全&#xff1a;密码机密钥管理的策略与实践 随着信息技术的飞速发展&#xff0c;信息安全已成为企业和社会关注的焦点。密码机作为加密通信和数据保护的关键设备&#xff0c;其密钥管理直接关系到整个信息系统的安全性。本文旨在探讨密码机密钥管理的策略与实践&…

如何根据协议请求去捕捉在个文件中发出去的

场景&#xff1a;随着业务越来越复杂&#xff0c;一个“触发”可能发出去N个协议&#xff0c;此时有某一个协议发生了报错&#xff0c;需要去找这个协议&#xff0c;去文件中走读逻辑&#xff0c;去找该协议&#xff0c;效率很慢&#xff0c;业务极其复杂的情况下&#xff0c;很…

渐变色代码主题你受得了吗

分享一个vscode编辑器的渐变色主题 效果图如下 vscode扩展搜索 gradient theme安装即可。

毕业设计选题:基于springboot+vue+uniapp的驾校报名小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

二级C语言2023-9易错题

1 二叉树结点数计算&#xff1a; 一棵二叉树有10个度为1的结点&#xff0c;7个度为2的结点&#xff0c;则该二叉树共有____个结点。 解&#xff1a; 2 指针&#xff1a; 有以下程序 #inctude<stdio.h> #include<stdlib.h> main() { int *a&#xff0c;*b&…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【扩展组件】上

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 子系统开发内核 轻量系统内核&#xff08;LiteOS-M&#xff09; 轻量系统内核&#…

CSS01-语法规范、基础选择器

一、CSS语法规范 示例&#xff1a; 二、CSS的基础选择器 选择器(选择符)就是根据不同需求把不同的标签选出来这就是选择器的作用。 简单来说&#xff0c;就是选择标签用的。 选择器的分类&#xff1a; 1、标签选择器 2、类选择器&#xff08;开发最常用&#xff09; 长字符命名…

本地搭建我的世界服务器(JAVA)简单记录

网上参考教程挺多的&#xff0c;踩了不少坑&#xff0c;简单记录一下&#xff0c;我做的是一个私人服务器&#xff0c;就是和朋友3、4个人玩。 笨蛋 MC 开服教程 先放一个比较系统和完整的教程&#xff0c;萌新可用&#xff0c;这个教程很详细&#xff0c;我只是记录一下自己的…

相亲交友系统源码 连接你我,不再孤单

在这个数字时代&#xff0c;人们的生活方式已经发生了巨大的变化。随着工作压力增大和社会竞争激烈化&#xff0c;很多人发现自己很难有时间和机会去结识新的朋友&#xff0c;更不用说找到适合自己的伴侣了。相亲交友系统正是在这种背景下应运而生&#xff0c;它不仅简化了交友…

操作系统 | 学习笔记 | | 王道 | 5.2 设备独立软件

5.2 设备独立性软件 IO核心子系统 磁盘IO也属于IO调度问题 5.2.1 与设备无关的软件 与设备无关的软件是I/O系统的最高层软件&#xff0c;它的下层是设备驱动程序。 设备保护&#xff1a; 操作系统需要实现文件保护功能&#xff0c;不同的用户对各个文件有不同的访问权限&am…

BUUCTF-MISC-隐藏的钥匙

下载题目文件&#xff0c;获得了一张格式为jpg的路飞图片 按照习惯&#xff0c;首先使用十六进制编译器打开文件&#xff0c;这里我使用winhex打开文件 首先考虑有没有flag直接隐写在文件中&#xff0c;按照图示步骤查找flag字段 我们查到了flag&#xff0c;通过经验和图中base…

[Python]案例驱动最佳入门:股票分析 Python数据分析与可视化实战

在股票市场中&#xff0c;价格波动和投资决策紧密相连。通过数据分析&#xff0c;投资者可以识别市场趋势、价格波动背后的规律&#xff0c;并做出明智的投资决策。Python凭借其强大的数据处理和可视化功能&#xff0c;在金融市场分析中被广泛应用。本文将通过一个假设的股票市…

java踩坑

1.mybatis在idea可以正常运行&#xff0c;但是打jar包后&#xff0c;就报链接超时&#xff0c;可能是参数设置有问题&#xff0c;但是idea自动忽略了。 出问题的配置&#xff1a;&#xff08;圈出来的地方乱码了&#xff0c;idea有纠错能力&#xff0c;它自动调整为正确的&…

three.js shader 实现天空中白云

three.js shader 实现天空中白云 预览&#xff1a; https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idwhiteCloud 更多案例 可见 预览&#xff1a; https://threehub.cn import * as THREE from "three"; import { OrbitControls …

web基础—dvwa靶场(十二)JavaScript Attacks

JavaScript Attacks (前端攻击) 本章节中的攻击旨在帮助您了解如何在浏览器中使用 JavaScript 以及如何对其进行操作&#xff0c;攻击可以通过分析网络流量来实现&#xff0c;但这不是本章节的重点而且可能要困难得多。 只需提交单词 “success” 即可攻击成功&#xff0c;显然…

开石开放式耳机怎么样?南卡、开石、声阔开放式耳机测评

​作为一名多年的数码博主&#xff0c;我本人也是个耳机发烧友&#xff0c;我最近注意到数码圈特别是蓝牙耳机圈中&#xff0c;有一种耳机特别火&#xff0c;叫开放式耳机&#xff0c;这类耳机的佩戴舒适度是非常高的&#xff0c;这也激起了我对这类耳机的兴趣&#xff0c;因此…