在Qt中读写文件我们常常会用到QFile、QByteArray、QDataStream和QTextStream,他们之间有什么区别呢?
文件打开方式:
QIODevice::NotOpen 0x0000 设备不打开.
QIODevice::ReadOnly 0x0001 设备 以只读的方式打开.
QIODevice::WriteOnly 0x0002 设备 以只写的方式打开.
QIODevice::ReadWrite ReadOnly | WriteOnly 设备以读写的方式打开,写入文件会覆盖之前的内容(打开文件期间多次写入不会覆盖).
QIODevice::Append 0x0004 设备以追加模式打开,以便将所有数据写入文件末尾,此模式下不能读文件.
QIODevice::Truncate 0x0008 如果可能,设备在打开之前会被截断。 设备的所有早期内容都将丢失。
QIODevice::Text 0x0010 读取时,行尾终止符被转换为’\ n’。 写入时,行尾终止符将转换为本地编码,例如Win32的“\ r \ n”。
QIODevice::Unbuffered 0x0020 绕过设备中的任何缓冲区。
注意:
普通写入会覆盖之前文件的内容部分或者全部,取决于写入内容的大小。
当同时使用Append方式和其它读文件方式打开文件时,读文件无效。
//清空文件内容并重写数据
void clearFileRewriteData(const QString &clearFileName, const QString &contentSource)
{
QStringList fileContentLst;
//读取数据来源文件
QFile sourceFile(contentSource);
if(sourceFile.open(QIODevice::ReadOnly))
{
while(!sourceFile.atEnd())
{
QString line = sourceFile.readLine();
fileContentLst << line;
}
}
QFile cartFile(clearFileName);
// cartFile.open(QFile::ReadWrite | QFile::Truncate);
cartFile.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate);
//写入cart文件内容
QTextStream writeStream(&cartFile);
QString writeContent = writeStream.readAll();
writeStream.setAutoDetectUnicode(true);
foreach(auto line, fileContentLst)
{
// writeStream << line;
writeStream << line << endl; //因为文件中已包含"\r\n",所以这里不用加endl
}
cartFile.close();
// sourceFile.flush();
sourceFile.close();
}
QByteArray类提供了一个字节数组。
QByteArray可用于存储原始字节(包括’\ 0’)和传统的8位’\ 0’终止字符串。使用QByteArray比使用const char *更方便。在幕后,它始终确保数据后跟’\ 0’终止符,并使用隐式共享(写时复制)来减少内存使用并避免不必要的数据复制。
QByteArray 是字节数组,可用于存储原始字节(包括 ‘\0’)和传统的 8 位以 ‘\0’ 结尾的字符串。使用 QByteArray 比使用 const char * 方便得多。在幕后,它始终确保数据后跟一个“\0”终止符,并使用隐式共享(copy-on-write)来减少内存使用并避免不必要的数据复制。
除了 QByteArray,Qt 还提供了 QString 类来存储字符串数据。对于大多数用途,QString 是理想的字符串类。它将其内容理解为 Unicode 文本(使用 UTF-16 编码),QString 在 Qt API 中贯穿始终。QByteArray 没有经过编码,储存的是原始的数据。
//大端格式,高字节在前
QDataStream out(&outData,QIODevice::ReadWrite);
out.setByteOrder(QDataStream::BigEndian);
//小端格式,低字节在前
QDataStream out(&outData,QIODevice::ReadWrite);
out.setByteOrder(QDataStream::LittleEndian);
QFile file("/home/cheng/TestPro/D_FileOperation/File/test.txt");
if(file.open( QIODevice::ReadWrite | QIODevice::Append ) )// QIODevice::Text |
{
QByteArray arr;
arr = file.read();
qDebug() << arr;
file.write("hello qfile!\n");
}
QDataStream 类为QIODevice提供序列化的二进制数据。
一个data stream 是一个编码后的二进制流,它与操作系统等无关。
你可以使用一个data stream去读写原始未编码的二进制数据。如果你想得到一个“parsing”的输入流,请查阅QTextStream
QDatastream类实现了对c++中基本数据类型的序列化工作,如:char、short、int、char*等。对于复杂的数据类型的序列化,是通过将其分解为基本原生的数据单元来进行。
data stream 跟 QIODevice紧密联系,一个QIODevice作为输入输出的媒介,它可以从写读出写入的数据。QFile就是一个I/O设备的例子。
void rewriteCartFile(const QString& filePath, const cartContext& context)
{
QFile fileModify(filePath);
if(!fileModify.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
{
qDebug() << "cart.par file open failed!";
return;
}
QDataStream dataStream(&fileModify);
QVector<int> numVec;
for(int i=0; i<100; i++)
{
numVec.push_back(i);
}
for(auto n : mumVec)
{
dataStream << n << " "
}
fileModify.close();
}
QTextStream 类(文本流)和 QDataStream 类(数据流)Qt 输入输出的两个核心类,其作用分别如下:
①、QTextStream 类:用于对数据进行文本格式的读/写操作,可在 QString、QIODevice或 QByteArray 上运行,比如把数据输出到 QString、QIODevice 或 QByteArray 对象上,或进行相反的操作。
void generateCartFile(const QString& filePath)
{
QFile cartFile(filePath);
if(!cartFile.open(QIODevice::ReadWrite | QIODevice::Text))
{
qDebug() << "Open cart.part file failed!";
return;
}
QStringList fileContent;
QTextStream readWrite(&cartFile);
QString line = readWrite.readLine();
fileContent << line;
cartFile.close();
}