qt binary file writing and reading - c++

void write(QString filename) {
QChar ch('b');
QFile mfile(filename);
if (!mfile.open(QFile::WriteOnly) {
qDebug() << "Could not open file for writing";
return;
}
QDataStream out(&mfile);
out.setVersion(QDataStream::Qt_4_8);
out << ch;
mfile.close();
}
open binary file and writing 'b'(binary)
void read(QString filename) {
QFile mfile(filename);
if (!mfile.open(QFile::ReadOnly)) {
qDebug() << "Could not open file for reading";
return;
}
QDataStream in(&mfile);
in.setVersion(QDataStream::Qt_4_8);
QChar mT;
in >> mT;
qDebug() << mT;
mfile.close();
}
read but not mT='b'.if ch and mT variables are int always mT=4 why?How can i writing ch(binary file) and read from binary file

the 4 number is the length of your data. QDataStream store length of your data before it to indicate how many bytes need to read to gain the written data. your data has been written after it.

Related

QFile. Device not open

I have problem with QFile.
QFile file1("file1.dat");
QFile file2("file2.dat");
if(file2.exists())
{
}
if(!file1.open(QIODevice::ReadOnly))
{
qDebug() << "Ошибка открытия для чтения";
}
if(!file2.open(QIODevice::WriteOnly))
{
qDebug() << "Ошибка открытия для записи";
}
QByteArray block = file1.readAll();
file2.write(block);
file1.close();
file2.close();
ERROR:
QIODevice::read (QFile, "file1.dat"): device not open
try to open file1.dat in read-write mode:
if(!file1.open(QIODevice::ReadWrite))
{
qDebug() << "Ошибка открытия";
}
Because if you open it just for reading, it cannot be created if it doesnt exist, or create it manually at first.
and in case that file is not opened you are not doing anything, so just for being sure check if both files were opened at first:
if(file1.isOpen() && file2.isOpen()){
QByteArray block = file1.readAll();
file2.write(block);
file1.close();
file2.close();
}

QTextStream is unable to write to file including "\t" with openmode QIODevice::Append

I tried to save some info to the text file using QTextStream. The code is given below:
QFile fi(QString("result.txt"));
fi.remove();
if(!fi.open(QIODevice::Append)) {
qDebug()<<"Cannot open file!";
return -1;
}
QTextStream ts(&fi);
float num = 1, error = 2;
ts<<"num="<<num<<"\t"<<"error="<<error<<endl;
However, the code does not work. The file is created, but nothing is written, i.e., the file is empty.
After some research, I found that I should change the open mode to QIODevice::Text | QIODevice::Append to make the code work. Otherwise the "\t" character must be removed. Does it mean that the QIODevice::Text is designed specifically for the special characters such as "\t" to work in writing to files?
I can't reproduce. The following works perfectly on Windows, OS X and Linux, with Qt 5.9. Please fix your example to be complete and reproducible. E.g. take the code below, and make it fail.
// https://github.com/KubaO/stackoverflown/tree/master/questions/stream-49779857
#include <QtCore>
QByteArray readAll(const QString &fileName) {
QFile f(fileName);
if (f.open(QIODevice::ReadOnly))
return f.readAll();
return {};
}
int main() {
auto tmp = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
auto fileName = QStringLiteral("%1/com.stackoverflow.questions.49779857-result.txt")
.arg(tmp);
QFile file(fileName);
file.remove();
if (!file.open(QIODevice::Append))
qFatal("Cannot open file!");
QTextStream ts(&file);
auto num = 1.0f, error = 2.0f;
ts << "num=" << num << "\t" << "error=" << error << endl;
file.close();
Q_ASSERT(file.exists());
Q_ASSERT(readAll(fileName) == "num=1\terror=2\n");
}

Do-while infinite loop in Qt

I'm trying to read in a file of trace addresses (each on their own line) and append to the front of each. This input file is intended to be the engine of a cache emulator i'm trying to build. I am having issues reading the file in without getting into an infinite loop. When I change the do-while to run on a false condition, I get the proper output for just the do segment. Therefore, I know I'm running into an infinite loop issue with how I worded my while segment. Maybe i'm fatigued and can't see the issue with this function:
void MainWindow::readFile(){
infoLabel->setText(tr("Invoked <b>File|Open</b>"));
QString filename="trace.txt";
QString path = QDir::currentPath();
QFile file("//Users//nathan1324//Desktop//trace.txt");
//file.open(QIODevice::ReadOnly);
if(!file.exists()){
qDebug() << "File cannot be found "<<filename;
qDebug() << " " << path;
}else{
qDebug() << filename<<" Opening...";
}
QString line;
textEdit->clear();
if (file.open(QIODevice::ReadOnly | QIODevice::Text)){
QTextStream stream(&file);
do {
line = stream.readLine();
textEdit->setText(textEdit->toPlainText()+"0x"+line+"\n");
qDebug() << "line: "<<line;
} while (!line.isNull());
}
file.close();
}
Any suggestions of an alternative way to write this function?
To add items use the append function of QTextEdit:
void QTextEdit::append(const QString & text)
Appends a new paragraph with text to the end of the text edit.
Note: The new paragraph appended will have the same character format
and block format as the current paragraph, determined by the position
of the cursor.
To iterate through the QTextStream atEnd()
bool QTextStream::atEnd() const
Returns true if there is no more data to be read from the QTextStream;
otherwise returns false. This is similar to, but not the same as
calling QIODevice::atEnd(), as QTextStream also takes into account its
internal Unicode buffer.
Code:
void MainWindow::readFile(){
infoLabel->setText(tr("Invoked <b>File|Open</b>"));
QString filename = "trace.txt";
QString path = QDir::currentPath();
QFile file("//Users//nathan1324//Desktop//trace.txt");
if(!file.exists()){
qDebug() << "File cannot be found "<<filename;
qDebug() << " " << path;
return;
}
QString line;
textEdit->clear();
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)){
qDebug() << "Could not open file" << filename;
return;
}
qDebug() << filename<<" Opening...";
QTextStream stream(&file);
while (!stream.atEnd()) {
line = stream.readLine();
if(!line.isNull()){
textEdit->append("0x"+line);
qDebug() << "line: "<<line;
}
}
file.close();
}
Use atEnd to detect the end of a stream:
bool QTextStream::atEnd() const
Returns true if there is no more data to be read from the QTextStream;
otherwise returns false. This is similar to, but not the same as
calling QIODevice::atEnd(), as QTextStream also takes into account its
internal Unicode buffer.
while (!stream.atEnd()) {
line = stream.readLine();
textEdit->setText(textEdit->toPlainText()+"0x"+line+"\n");
qDebug() << "line: "<<line;
}

How to detect an image file is svg-fomat strictly?

QFile file(filepath);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "DetectImageFormat() failed to open file:" << filepath;
return "";
}
const QByteArray data = file.read(1024);
// Check svg file. but sometimes i get the data failed!
if (data.indexOf("<svg") > -1) {
return "svg";
}

Why is the QByteArray read from a file smaller than the newly downloaded QByteArray?

I am attempting to compare a QByteArray of an already saved html file with a QByteArray that was just downloaded. I have to convert the QString of the file's contents to QByteArray in order to compare them (or vice versa) and comparing bytes seems like the cleanest method, however when converted from QString to QByteArray, the size of the new QByteArray is smaller than what it should be. QByteArray QString::toLocal8Bit() const states that if it is undefined, the characters will be suppressed or replaced. It also said that it uses toLatin1() by default and tried to use ASCII since that is what a website is encoded in. I still get the same results.
bool NewsBulletin::compareDownload(QByteArray new_contents, QString filename)
{
bool return_what = false;
qDebug() << "I am in compareDownload";
// qDebug() << new_contents[1];
// qDebug() << new_contents[1] << endl
// << new_contents[2];
QFile file(application_path + filename);
if (file.exists())
{
// QString new_contents_qstr(new_contents);
file.open(QIODevice::ReadOnly | QIODevice::Text);
QTextStream in(&file);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("ASCII"));
QString file_contents = in.readAll();
QByteArray file_byte_array = file_contents.toLocal8Bit();
qDebug() << "outputting new file array";
qDebug() << new_contents[5] << new_contents.size();
qDebug() << "outputting old file array";
qDebug() << file_byte_array[5] << file_byte_array.size();
for (int i=0; i<=file_byte_array.size(); i++)
{
if (file_byte_array[i] != new_contents[i])
{
return_what = true;
break;
}
else if (i == file_byte_array.size())
{
qDebug() << "compareDownload will return false, duplicate file.";
return_what = false;
}
}
}
else
{
qDebug() << "compareDownload will return true, DNE.";
return_what = true;
}
return return_what;
}
The output of the qDebug() from the function is:
I am in compareDownload
outputting new file array
T 64704
outputting old file array
T 64576
After reading the api for hours, I found the reason for the bytes being different.
file.open(QIODevice::ReadOnly | QIODevice::Text);
QIODevice::Text needs to be removed. This flag changes end of line terminators into the terminator for cpp, "\n", thus giving a byte difference.