当前位置: 首页 > news >正文

Qt中QFile、QByteArray QDataStream和QTextStream区别及示例

在Qt中,QFileQByteArrayQDataStreamQTextStream是常用的文件和数据处理类。

主要功能和区别

  1. QFile

QFile是用于读写文本和二进制文件以及资源的I/O设备。可以单独使用QFile,或者更方便地与QTextStreamQDataStream一起使用。

通常在构造函数中传入文件名,但也可以随时使用setFileName()进行设置。QFile期望文件分隔符为’/‘,不论操作系统为何。不支持使用分隔符(例如’')。

可以使用exists()检查文件是否存在,并使用remove()删除文件。(更高级的文件系统相关操作由QFileInfoQDir提供。)

文件使用open()打开,使用close()关闭,并使用flush()刷新。通常使用QDataStreamQTextStream进行数据的读取和写入,但也可以使用QIODevice继承的函数read()readLine()readAll()write()进行操作。QFile还继承了getChar()、putChar()和ungetChar(),可以逐个字符地进行操作。

使用size()可以获取文件的大小。可以使用pos()获取当前文件位置,或者使用seek()移动到新的文件位置。如果已经到达文件末尾,atEnd()返回true。

  1. QByteArray

QByteArray类提供了一个字节数组。
QByteArray可用于存储原始字节(包括’\0’)和传统的8位’\0’终止的字符串。使用QByteArray比使用const char *更方便。在幕后,它始终确保数据后跟’\0’终止符,并使用隐式共享(写时复制)来减少内存使用和避免无谓的数据复制。
除了QByteArray,Qt还提供了QString类用于存储字符串数据。对于大多数情况,应使用QString类。它存储16位Unicode字符,使得在应用程序中存储非ASCII/非Latin-1字符变得容易。此外,在Qt API中广泛使用QString。QByteArray适用的两种主要情况是当需要存储原始二进制数据时,以及内存保护至关重要的情况(例如,在Qt for Embedded Linux中)。
初始化QByteArray的一种方法是将const char *传递给其构造函数。例如,以下代码创建一个包含数据"Hello"的大小为5的字节数组:

  QByteArray ba("Hello");

尽管size()为5,字节数组还在末尾保留了一个额外的’\0’字符,以便在使用需要指向底层数据的指针的函数(例如调用data())时,所指向的数据保证是以’\0’结尾的。
QByteArray会对const char *数据进行深拷贝,因此您可以稍后进行修改而不会出现副作用。(如果出于性能原因,您不想对字符数据进行深拷贝,请改用QByteArray::fromRawData()。)

另一种方法是使用resize()设置数组的大小,并逐个字节初始化数据。QByteArray使用基于0的索引,就像C++数组一样。要访问特定索引位置的字节,可以使用operator。对于非const字节数组,operator返回一个字节的引用,可以在赋值的左侧使用。例如:

  QByteArray ba;ba.resize(5);ba[0] = 0x3c;ba[1] = 0xb8;ba[2] = 0x64;ba[3] = 0x18;ba[4] = 0xca;

对于只读访问,使用at()的替代语法:

  for (int i = 0; i < ba.size(); ++i) {if (ba.at(i) >= 'a' && ba.at(i) <= 'f')cout << "Found character in range [a-f]" << endl;}

at()可能比operator更快,因为它永远不会导致深拷贝发生。
要一次提取多个字节,请使用left()right()mid()
QByteArray可以嵌入’\0’字节。size()函数始终返回整个数组的大小,包括嵌入的’\0’字节,但不包括QByteArray添加的终止’\0’。例如:

  QByteArray ba1("ca\0r\0t");ba1.size();                     // 返回2。ba1.constData();                // 返回带有终止\0的"ca"。QByteArray ba2("ca\0r\0t", 3);ba2.size();                     // 返回3。ba2.constData();                // 返回带有终止\0的"ca\0"。QByteArray ba3("ca\0r\0t", 4);ba3.size();                     // 返回4。ba3.constData();                // 返回带有终止\0的"ca\0r"。const char cart[] = {'c', 'a', '\0', 'r', '\0', 't'};QByteArray ba4(QByteArray::fromRawData(cart, 6));ba4.size();                     // 返回6。ba4.constData();                // 返回不带终止\0的"ca\0r\0t"。

如果要获取数据长度,直到但不包括第一个’\0’字符,可以在字节数组上调用qstrlen()。
在调用resize()后,新分配的字节的值是未定义的。要将所有字节设置为特定值,请调用fill()。
要获取指向实际字符数据的指针,请调用data()或constData()。这些函数返回指向数据开头的指针。该指针保证在QByteArray上调用非const函数之前保持有效。还保证除非QByteArray是从原始数据创建的,否则数据以’\0’字节结尾。QByteArray自动提供此’\0’字节,并且不计入size()中。
QByteArray提供了以下基本函数来修改字节数据:append()、prepend()、insert()、replace()和remove()。例如:

  QByteArray x("and");x.prepend("rock ");         // x == "rock and"x.append(" roll");          // x == "rock and roll"x.replace(5, 3, "&");       // x == "rock & roll"

replace()remove()函数的前两个参数是要开始擦除的位置和应该擦除的字节数。
当将数据追加到非空数组时数组将被重新分配并将新数据复制到其中。您可以通过调用reserve()来避免此行为,它预分配一定数量的内存。您还可以调用capacity()来了解QByteArray实际分配了多少内存。追加到空数组中的数据不会被制。
经常要求从字节数组中删除空白字符(‘\n’、‘\t’、''等)。如果要从QByteArray两端删除空白字符,请使用trimmed()。如果要从QByteArray两端删除空白字符,并且在字节数组中多个连续的空白字符替换为单个空格字符,请使用simplified()。
如果要在QByteArray中查找特定字符或子字符串的所有出现,可以使用indexOf()或lastIndexOf()。前者从给定的索引位置向前搜索,后者向后搜索。如果找到了字符或子字符串,两者都返回其索引位置;否则,它们返回-1。例如,以下是查找特定子字符串的典型循环:

  QByteArray ba("We must be <b>bold</b>, very <b>bold</b>");int j = 0;while ((j = ba.indexOf("<b>", j)) != -1) {cout << "Found <b> tag at index position " << j << endl;++j;}

如果只是想检查一个QByteArray是否包含特定字符或子字符串,请使用contains()。如果想要找出特定字符或子字符串在字节数组中出现的次数,请使用count()。如果想要用另一个值替换所有出现的特定值,请使用带有两个参数的replace()重载之一。
可以使用诸如operator<(), operator<=(), operator==(), operator>=()等重载运算符来比较QByteArray。比较仅基于字符的数值值,非常快速,但不符合人的预期。对于排序用户界面字符串,QString::localeAwareCompare()是更好的选择。

由于历史原因,QByteArray区分空字节数组和空字节数组。空字节数组是通过使用QByteArray的默认构造函数或通过将(const char *)0传递给构造函数进行初始化的字节数组。大小为0的任何字节数组都是空字节数组。空字节数组不一定是null字节数组:

  QByteArray().isNull();          // 返回trueQByteArray().isEmpty();         // 返回trueQByteArray("").isNull();        // 返回falseQByteArray("").isEmpty();       // 返回trueQByteArray("abc").isNull();     // 返回falseQByteArray("abc").isEmpty();    // 返回false

除了isNull()函数外,所有其他函数都将null字节数组视为与空字节数组相同。例如,对于null字节数组,data()返回指向 ‘\0’ 字符的指针(非空指针),并且QByteArray()与QByteArray(“”)相等。我们建议始终使用isEmpty(),避免使用isNull()。

  1. QDataStream

QDataStream类提供了将二进制数据序列化到QIODevice的功能。
数据流是一个二进制编码信息流,完全独立于主机计算机的操作系统、CPU或字节顺序。例如,由Windows PC编写的数据流可以被运行Solaris系统的Sun SPARC读取。
您还可以使用数据流来读写原始的未编码的二进制数据。如果您需要一个"解析"输入流,请参见QTextStream
QDataStream类实现了C++基本数据类型(如char、short、int、char *等)的序列化。更杂数据的序列化是通过将数据分解为基本单元来完成的。

数据流与QIODevice紧密配合。QIODevice代表可以从中读取数据或向其写入数据的输入/输出介质。QFile类是一个I/O设备的示例。

示例(将二进制数据写入数据流):

  QFile file("file.dat");file.open(QIODevice::WriteOnly);QDataStream out(&file);   // 将数据序列化到文件中out << QString("the answer is");   // 序列化字符串out << (qint32)42;        // 序列化整数

示例(从数据流读取二进制数据):

  QFile file("file.dat");file.open(QIODevice::ReadOnly);QDataStream in(&file);    // 从文件中读取已序列化的数据QString str;qint32 a;in >> str >> a;           // 提取"the answer is"和42

每个写入流中的项目都以预定义的二进制格式写入,该格式取决于项目的类型。支持的Qt类型包括QBrush、QColor、QDateTime、QFont、QPixmap、QString、QVariant等。有关支持数据流的所有Qt类型的完整列表,请参见序列化Qt数据类型。
对于整数,最好始终将其强制转换为Qt整数类型进行写入,并读取回到相同的Qt整数类型中。这样可以确保您获得所需的整数大小,并将您与编译器和平台的差异隔离开来。
举个例子,一个char *字符串被写为一个32位整数,该整数等于字符串长度,包括’\0’字节,后跟字符串的所有字符,包括’\0’字节。当读取一个char *字符串时,首先读取4个字节以创建32位长度值,然后读取相同数量的字符来创建包含’\0’终止符的char *字符串。
初始的I/O设备通常在构造函数中设置,但可以使用setDevice()进行更改。如果已到达数据的末尾(或者没有设置I/O设备),atEnd()将返回true。

版本控制
自Qt 1.0以来,QDataStream的二进制格式已发生了演变,并且可能会继续着Qt的变化而发展。在输入或输出复杂类型,非常重要的一点是确保在读取和写入时使用相同版本的(version())。如果您需要前向和后向兼容性,您可以在应用程序中硬编码版本号:

  stream.setVersion(QDataStream::Qt_4_0);

如果您正在生成一种新的二进制数据格式,例如您的应用程序创建的文档文件格式,您可以使用QDataStream以便于移植的格式写入数据。通常,您会写一个简短的头部,包含一个标识字符串和一个版本号,以便为将来的扩展留出空间。例如:

  QFile file("file.xxx");file.open(QIODevice::WriteOnly);QDataStream out(&file);// 写入包含"魔术数字"和版本号的头部out << (quint32)0xA0B0C0D0;out << (qint32)123;out.setVersion(QDataStream::Qt_4_0);//入数据out << lots_of_interest_data;

然后使用以下代码进行读取:

  QFile file("file.xxx");file.open(QIODevice::ReadOnly);QDataStream (&infile);// 读取并检查头部quint32 magic;in >> magic;if (magic != 0xA0B0C0D0)return XXX_BAD_FILE_FORMAT;// 读取版本号qint32 version;in >> version;if (version < 100)return XXX_FILE_TOO_OLD;if (version > 123)return XXX_BAD_FILE_TOO_NEW;if (version <= 110)in.setVersion(QDataStream::Qt_3_2);elsein.setVersion(QDataStream::Qt_4_0);// 取数据in >> lots_of_interesting_data;if (version >= 120)in >> data_new_in_XXX_version_1_2;in >> other_interesting_data;

在序列化数据时,您可以选择使用哪种字节顺序。默认设置为big endian(最高位在前)。将其更改为little endian会破坏可移植性(除非读取方也更改为little endian)。我们建议保持此设置,除非有特殊需求。
读取和写入原始二进制数据
您可能希望直接从数据流中读取/写入自己的原始二进制数据。可以使用readRawData()将数据从流中读取到预先分配的char *中。类似地,可以使用writeRawData()将数据写入到流中。注意,数据的任何编码/解码都必须由您自己完成。
另一对类似的函数是readBytes()writeBytes()。与原始函数的不同之处在于:readBytes()读取一个quint32,将其视为要读取的长度,然后将该数量的字节读入预先分配的char *中;writeBytes()写入包含数据长度的quint32,然后是数据本身。请注意,数据的任何编码/解码(除了长度quint32之外)都必须由您自己完成。

  1. QTextStream

QTextStream类提供了一个方便的界面,用于读写文本。
QTextStream可以操作QIODeviceQByteArrayQString。使用QTextStream的流操作符,您可以方便地读写单词、行和数字。对于生成文本,QTextStream支持字段填充和对齐的格式选项,以及数字的格式化。示例:

  QFile data("output.txt");if (data.open(QFile::WriteOnly | QFile::Truncate)) {QTextStream out(&data);out << "Result: " << qSetFieldWidth(10) << left << 3.14 << 2.7;// 输出 "Result: 3.14      2.7       "}

通常还会使用QTextStream来读取控制台输入和写入控制台输出。QTextStream具有区域设置意识,并将自动使用正确的编解码器对标准输入进行解码。示例:

  QTextStream stream(stdin);QString line;while (stream.readLineInto(&line)) {...}

除了使用QTextStream的构造函数外,还可以通过调用setDevice()或setString()设置QTextStream操作的设备或字符串。可以通过调用seek()来定位到某个位置,当没有数据可以读取时,调用atEnd()将返回true。如果调用flush(),QTextStream将会将其写缓冲区中的所有数据清空到设备,并调用设备上的flush()。
在内部,QTextStream使用基于Unicode的缓冲区,QTextCodec用于自动支持不同的字符集。默认情况下,读取和写入使用QTextCodec::codecForLocale(),但也可以通过调用setCodec()来设置编解码器。还支持自动Unicode检测。当启用此功能时(默认行为),QTextStream将检测UTF-16或UTF-32的BOM(字节顺序标记),并在读取时切换到适当的UTF编解码器。QTextStream默认不会写入BOM,但可以通过调用setGenerateByteOrderMark(true)启用。当QTextStream直接操作QString时,编解码器被禁用。

使用QTextStream读取文本文件有三种常见方式:

  • 按块读取,通过调用readLine()或readAll()。
  • 逐个单词读取。QTextStream支持流式读取到QString、QByteArray和char*缓冲区中。单词由空格分隔,并自动跳过前导空格。
  • 逐个字符读取,通过流式读取到QChar或char类型中。这种方法通常用于方便地处理输入,无论字符编码和行尾的语义如何。要跳过空格,调用skipWhiteSpace()。\

由于文本流使用缓冲区,您不应该使用超类的实现从流中读取。例如,如果您有一个QFile并直接使用QFile::readLine()从中读取,而不使用流,文本流的内部位置将与文件的位置不同步。
默认情况下,当从文本流中读取数字时,QTextStream会自动检测数字的进制表示。例如,如果数字以"0x"开头,它被认为是十六进制形式。如果以1-9的数字开头,它被认为是十进制形式,依此类推。您可以通过调用setIntegerBase()设置整数的进制,从而禁用自动检测。示例:

  QTextStream in("0x50 0x20");int firstNumber, secondNumber;in >> firstNumber;             // firstNumber == 80in >> dec >> secondNumber;     // secondNumber == 0char ch;in >> ch;                      // ch == 'x'

QTextStream支持许多用于生成文本的格式选项。您可以通过调用setFieldWidth()和setPadChar()设置字段宽度和填充字符。使用setFieldAlignment()设置每个字段内的对齐方式。对于实数,可以调用setRealNumberNotation()和setRealNumberPrecision()设置所生成数字的表示(智能表示、科学表示、定点表示)和精度(数字位数)。还可以通过setNumberFlags()设置其他一些数字格式选项。

与标准C++库中的一样,QTextStream还定义了几个全局操纵函数:

操纵函数描述
bin与setIntegerBase(2)相同。
oct与setIntegerBase(8)相同。
dec与setIntegerBase(10)相同。
hex与setIntegerBase(16)相同。
showbase与setNumberFlags(numberFlags()
forcesign与setNumberFlags(numberFlags()
forcepoint与setNumberFlags(numberFlags()
noshowbase与setNumberFlags(numberFlags() & ~ShowBase)相同。
noforcesign与setNumberFlags(numberFlags() & ~ForceSign)相同。
noforcepoint与setNumberFlags(numberFlags() & ~ForcePoint)相同。
uppercasebase与setNumberFlags(numberFlags()
uppercasedigits与setNumberFlags(numberFlags()
lowercasebase与setNumberFlags(numberFlags() & ~UppercaseBase)相同。
lowercasedigits与setNumberFlags(numberFlags() & ~UppercaseDigits)相同。
fixed与setRealNumberNotation(FixedNotation)相同。
scientific与setRealNumberNotation(ScientificNotation)同。
left与setFieldAlignment(AlignLeft)相同。
right与setFieldAlignment(AlignRight)相同。
center与setFieldAlignment(AlignCenter)相同。
endl与operator<<(‘\n’)和flush()相同。
flush与flush()相同。
reset与reset()相同。
ws与skipWhiteSpace()相同。
bom与setGenerateByteOrderMark(true)相同。

此外,Qt提供了三个带有参数的全局操纵符:qSetFieldWidth()qSetPadChar()qSetRealNumberPrecision()

总结就是,QFile用于文件的读写操作,QByteArray用于处理二进制数据,QDataStream用于二进制数据的序列化和反序列化,而QTextStream用于文本数据的读写和处理。它们各自有不同的功能和适用场景,根据具体需求选择合适的类进行操作。

用法及示例

当使用Qt中的QFile、QByteArray、QDataStream和QTextStream时,可以按照以下示例来使用它们的成员函数:

  1. QFile的使用示例:
#include <QFile>
#include <QDebug>
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);// 创建一个QFile对象QFile file("data.txt");// 打开文件以进行写入if (file.open(QIODevice::WriteOnly)){// 写入数据到文件QString data = "Hello, World!";file.write(data.toUtf8());// 关闭文件file.close();}// 打开文件以进行读取if (file.open(QIODevice::ReadOnly)){// 读取文件中的数据QByteArray data = file.readAll();// 将字节数组转换为字符串并输出QString str(data);qDebug() << str;// 关闭文件file.close();}return a.exec();
}
  1. QByteArray的使用示例:
#include <QByteArray>
#include <QDebug>
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);// 创建一个QByteArray对象QByteArray byteArray;// 向字节数组添加数据byteArray.append("Hello");byteArray.append(" ");byteArray.append("World!");// 输出字节数组中的数据qDebug() << byteArray;// 清空字节数组byteArray.clear();return a.exec();
}
  1. QDataStream的使用示例:
#include <QDataStream>
#include <QFile>
#include <QDebug>
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);// 创建一个QFile对象QFile file("data.bin");// 打开文件以进行写入if (file.open(QIODevice::WriteOnly)){// 创建一个QDataStream对象,并传入QFile对象QDataStream stream(&file);// 写入整数到流中int value = 42;stream << value;// 关闭文件file.close();}// 打开文件以进行读取if (file.open(QIODevice::ReadOnly)){// 创建一个QDataStream对象,并传入QFile对象QDataStream stream(&file);// 从流中读取整数int value;stream >> value;// 输出取到的整数qDebug() << value;//闭文件file.close();}return a.exec();
}
  1. QTextStream的使用示例:
#include <QTextStream>
#include <QFile>
#include <QDebug>
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);// 创建一个QFile对象QFile file("data.txt");// 打开文件以进行写if (file.open(QIODevice::WriteOnly | QIODevice::Text)){// 创建一个QTextStream对象,并传入QFile对象QTextStream stream(&file);// 写入文本到流中stream << "Hello, World!";// 关闭文件file.close();}// 打开文件以进行读取if (file.open(QIODevice::ReadOnly | QIODevice::Text)){// 创建一个QTextStream对象,并传入QFile对象QTextStream stream(&file);// 从流中读取文本QString text = stream.readAll();// 输出读取到的文本qDebug() << text;// 关闭文件file.close();}return a.exec();
}

示例分别使用QFile来读写文件、使用QByteArray处理字节数组、使用QDataStream进行二进制数据的序列化和反序列化、以及使用QTextStream进行文本数据的读写处理。

综合用法

#include <QFile>
#include <QByteArray>
#include <QDataStream>
#include <QTextStream>
#include <QDebug>
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);// 创建一个QByteArray对象QByteArray byteArray;// 向字节数组添加数据byteArray.append("Hello, World!");// 创建一个QFile对象QFile file("data.bin");// 打开文件以进行写入if (file.open(QIODevice::WriteOnly)){// 创建一个QDataStream对象,并传入QFile对象QDataStream dataStream(&file);// 将字节数组写入流dataStream << byteArray;// 关闭文件file.close();}// 打开文件以进行读取if (file.open(QIODevice::ReadOnly)){// 创建一个QDataStream对象,并传入QFile对象QDataStream dataStream(&file);// 创建一个新的QByteArray对象QByteArray newDataArray;// 从流中读取字节数组dataStream >> newDataArray;// 创建一个QTextStream对象QTextStream textStream(&newDataArray);// 读取字符串数据QString text = textStream.readAll();// 输出读取到的字符串qDebug() << text;// 关闭文件file.close();}return a.exec();
}

输出结果

在这里插入图片描述
示例中,首先创建一个QByteArray对象并向它添加数据。然后,将这个字节数组写入到一个文件中(使用QDataStream),并将文件关闭。接下来,再次打开文件并使用QDataStream从中读取字节数组。最后,使用QTextStream读取字节数组中的字符串数据,并将其输出到控制台。

相关文章:

Qt中QFile、QByteArray QDataStream和QTextStream区别及示例

在Qt中&#xff0c;QFile、QByteArray、QDataStream和QTextStream是常用的文件和数据处理类。 主要功能和区别 QFile&#xff1a; QFile是用于读写文本和二进制文件以及资源的I/O设备。可以单独使用QFile&#xff0c;或者更方便地与QTextStream或QDataStream一起使用。 通常在…...

【操作系统】32进制小数转16进制

要将32进制的小数转换为16进制&#xff0c;可以按照以下步骤进行&#xff1a; 将32进制小数转换为10进制。可以使用上述提到的方法&#xff0c;将32进制小数转换为对应的10进制数。 将10进制数转换为16进制。使用常规的方法将10进制数转换为16进制数。可以将10进制数不断除以1…...

C#实现数据导出任一Word图表的通用呈现方法及一些体会

疲惫的修改 应人才测评产品的需求&#xff0c;导出测评报告是其中一个重要的环节&#xff0c;报告的文件类型也多种多样&#xff0c;其中WORD输出也扮演了一个重要的角色。 实现方法比较简单&#xff0c;结合分析结果数据&#xff0c;通过WORD模板文件进行替换输出。在实现的…...

2023-10 字节跳动面试整个过程 golang营销服务开发岗位

面试整个过程大约1个小时回答的中规中矩吧 很多问题回答的不具体 难受死我了非常简单的算法题下面列出来了面试步骤这里面有一点就是面试官本来想问问我数据结构这一块的问题 但是我说不太熟悉 他就没问了 1. 简单介绍个人信息 略2. 介绍简历上的项目 略3. 什么是分布式事务 主…...

Java类名的命名规范

Java中的类名必须以字母或者下划线开头&#xff0c;不能以数字开头。 类名的每个单词的首字母必须大写&#xff0c;这被称为帕斯卡命名法。 此外&#xff0c;类名不能使用关键字或保留字&#xff0c;不能使用数字除了_和$之外的任何符号&#xff0c;中间不能添加空格。 如果…...

【c++Leetcode】141. Linked List Cycle

问题入口 思想&#xff1a;Floyds Tortoise and Hare 这个算法简单来说就是设置一个慢指针&#xff08;一次移动一个位置&#xff09;和一个快指针&#xff08;一次移动两个位置&#xff09;。在遍历过程中&#xff0c;如果慢指针和快指针都指向同一个元素&#xff0c;证明环…...

Visa股票仍然值得投资

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 总结&#xff1a; &#xff08;1&#xff09;尽管Visa(V)的估值高于市场平均水平&#xff0c;但仍值得买入。 &#xff08;2&#xff09;Visa拥有强劲的基本面&#xff0c;销售额和每股收益一直在稳定增长&#xff0c;股息…...

【Android知识笔记】RecyclerView专题

RecyclerView工作流程 RecyclerView 的使用方法简单回顾: // 1. 添加gradle依赖 implementation androidx.recyclerview:recyclerview:1.1.0// 2. 布局文件 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http:…...

从头开始使用 KNN 进行 KNN 和 MNIST 手写数字识别的初学者指南

一、说明 MNIST &#xff08;“修改后的国家标准与技术研究所”&#xff09;是事实上的计算机视觉“hello world”数据集。自 1999 年发布以来&#xff0c;这个经典的手写图像数据集一直作为分类算法基准测试的基础。随着新的机器学习技术的出现&#xff0c;MNIST 仍然是研究人…...

文件的基本操作(创建文件,删除文件,读写文件,打开文件,关闭文件)

1.创建文件(create系统调用) 1.进行Create系统调用时&#xff0c; 需要提供的几个主要参数: 1.所需的外存空间大小&#xff08;如:一个盘块&#xff0c;即1KB) 2&#xff0e;文件存放路径&#xff08;“D:/Demo”) 3.文件名&#xff08;这个地方默认为“新建文本文档.txt”) …...

微积分(二) 导数与微分

前言 导数反映了函数值相对于自变量的变化快慢程度&#xff0c;而微分则表明当自变量有微小变化时&#xff0c;函数值大体上变化多少 瞬时速度的解决——极限 牛顿采用了一种无限逼近的方法。 平均速度的定义:如果一个物体在一段时间△t内位移了s,它在这段时间内的平均速度…...

go语言Array 与 Slice

有的语言会把数组用作常用的基本的数据结构&#xff0c;比如 JavaScript&#xff0c;而 Golang 中的数组(Array)&#xff0c;更倾向定位于一种底层的数据结构&#xff0c;记录的是一段连续的内存空间数据。但是在 Go 语言中平时直接用数组的时候不多&#xff0c;大多数场景下我…...

Ubuntu自启动设置

ubuntu中编写shell脚本开机自动启动(推荐)_Linux_脚本之家 1. vim test.sh 2. #!/bin/bash ### BEGIN INIT INFO # Provides: test # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 …...

Qwen 通义千问 14B 模型,长文本问答效果测试

千问的config&#xff1a; seq_len2k max_position_embedding8k 注意&#xff0c;以下实验结果的字数是token数&#xff0c;不是中文字符数。 不使用动态ntk 12000字输入&#xff1a; 乱码5000字输入&#xff1a;乱码1500字输入&#xff1a;正常 不使用动态ntk&#xff0c…...

Prefix-Tuning源码解析

Prefix-Tuning源码解析 Prefix-Tuning在PEFT包中的源码实现 改写自Based on https://github.com/THUDM/P-tuning-v2/blob/main/model/prefix_encoder.py import torch from transformers import PretrainedConfigclass PrefixEncoder(torch.nn.Module):rThe torch.nn model t…...

Java EE-servlet API 三种主要的类

上述的代码如下&#xff1a; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.i…...

简单谈谈我参加数据分析省赛的感受与体会

数据分析省赛的感受与体会 概要考试前的感受与体会考试注意事项小结 概要 大数据分析省赛指的是在省级范围内举办的大数据分析竞赛活动。该竞赛旨在鼓励和推动大数据分析领域的技术创新和人才培养&#xff0c;促进大数据技术与应用的深度融合&#xff0c;切实解决实际问题。参…...

rust学习——泛型 (Generics)

文章目录 泛型 Generics泛型详解结构体中使用泛型枚举中使用泛型方法中使用泛型为具体的泛型类型实现方法 const 泛型&#xff08;Rust 1.51 版本引入的重要特性&#xff09;const 泛型表达式 泛型的性能 泛型 Generics Go 语言在 2022 年&#xff0c;就要正式引入泛型&#xf…...

【USRP】通信之有线通信

有线通信&#xff1a; 有线通信是指使用物理线路或媒体&#xff08;例如&#xff0c;铜线、同轴电缆、光纤&#xff09;进行数据、声音和视频传输的通信方式。由于它依赖于实体传输媒介&#xff0c;有线通信通常具有较高的稳定性和可靠性&#xff0c;并能支持长距离的高带宽通…...

【算法】BFS

BFS广度优先搜索 1. 概念理解 广度优先搜索(BFS)是指&#xff0c;以一个起点(原点、结点、根)为基本点&#xff0c;向其所要搜索的方向扩散&#xff0c;并最终到达目标点的搜索方法。 2. 应用方向 有迷宫问题、层序遍历等应用。 3. 迷宫问题 以迷宫问题为例。 当想要从左…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...