I have a file name into a QByteArray
QString file_name = "icon.jpg";
QByteArray qba1; qba+=file_name;
I have the contents of a file into a QByteArray
QFile file("C:\\Devel\\icon.jpg");
if (file.open(QIODevice::ReadOnly)){
QByteArray content = file.readAll();
}
How to connect the file name and the contents of one variable of type QByteArray?
How to parse this variable QByteArray back to file name and content?
Simplest way is to start with the length of the filename, then the filename itself, followed by the data. Parsing the data back is as simple as reading the filename-length first, read the filename, then the data.
QByteArray qbaFileName((const char*)(file_name.utf16()), file_name.size() * 2);
QByteArray byteArray;
QDataStream stream(&byteArray, QIODevice::WriteOnly);
stream << (int)qbaFileName.size(); // put length of filename on stream
stream << qbaFileName; // put filename on stream
stream << file.readAll(); // put binary data on stream
Related
So I am trying to convert a QFile into a QString by doing the following:
void MainWindow::openTemplateFile(QString location)
{
if (location.isEmpty())
return;
else
{
QString variable;
templateFile.setFileName(location);
if (!templateFile.open(QFile::ReadOnly | QFile::Text))
{
QMessageBox::information(this, "Unable to open template",
templateFile.errorString());
return;
}
else // file opened and ready to read from
{
QTextStream in(&templateFile);
QString fileText = in.readAll();
qDebug() << templateFile.size() << in.readAll();
}
}
}
However, in I get the following result in the debug console:
48 ""
templateFile does exist and is part of the MainWindow class. This is also simplified code - in the actual program I read chars from the file and it works correctly. The location string is a result of the QFileDialog::getOpenFileName function, which I open a txt file with.
You call readAll() twice. The second time, the stream is positioned at end-of-file, and so readAll() has nothing to read and returns an empty string. Print fileText in your debug output instead.
I'm new to Qt.In my app,I want to press a button and it will come out a QFileDialog to let me select the file in file system .So how to do that?
After that , here is my problem, I don't know which API in Qt works just like "open" in POSIX ? I think if I can open the file in the right way , this API will return me a file descriptor and I can read/write this file like open did in posix.
I read some documents and found some classes such as QFile QDataStream but I don't know if they are exactly what I want.
Those are exactly what you are looking for.
In particular, you can use some of the static methods of QFileDialog to get a reference to the file you want to open, like:
static QString getOpenFileName(QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, Options options = 0)
and then use a QFile and QDataStream or QTextStream to read the contents.
You'd use QDataStream for reading binary data most of the times, like follows:
QFile f(fileName);
if (f.open(QIODevice::ReadOnly)) {
QDataStream stream(&f);
int data;
stream >> data;
}
Otherwise you can read plain text with QTextStream as follows:
QTextStream stream(&f);
QString line;
do {
line = stream.readLine();
/* do something with the line */
} while (!line.isNull());
Qt docs are pretty complete, you just have to take your time and read them. There's also plenty of examples.
Only Reading:
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open file"), "", tr("all Files ()"));
QFile file(fileName);
if(file.open(QIODevice::ReadOnly)){
QByteArray arr = file.readAll();
file.close();
}
Only Writing:
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open file"), "", tr("all Files ()"));
QFile file(fileName);
if(file.open(QIODevice::WriteOnly)){
file.write(QBtyeArray("Heelo World"));
file.close();
}
Read and Write:
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open file"), "", tr("all Files ()"));
QFile file(fileName);
if(file.open(QIODevice::ReadWrite)){
QByteArray arr = file.readAll();
arr += " From Earth";
file.write(arr);
file.close();
}
if you use QDatastream you do not need resolve how many part you have written before,follow Below Code and I always use this method;
QBuffer buffer;
buffer.open(QIODevice::WriteOnly);
QDatastream out(&buffer);
out << QString("Hello World QString");
out << QByteArray("Hello World QByteArray");
out << int(55);
buffer.close();
QFile file(fileName);
if(file.open(QIIDevice::WriteOnly)){
file.write(buffer.data());
file.close();
}
and reading this file
QFile file(fileName);
if(file.open(QIIDevice::WriteOnly)){
QDatastream in(&file);
QString str;
QByteArray arr;
int integer;
in >> str;
in >> arr;
in >> integer;
file.close();
}
str is "Hello World QString";
arr is "Hello World QByteArray";
integer is 55;
QDataStream is adding extra bytes to file for your parts and if you read it with QDataStream, QDataStream solve how many parts and each part bytes instead of you.
I am trying to follow the tutorial here and serialize Qt objects. Here is my code:
QFile file("/Users/kaustav/Desktop/boo.dat");
if (!file.open(QIODevice::WriteOnly)) {
qDebug() << "Cannot open file for writing: "
<< qPrintable(file.errorString()) << endl; //no error message gets printed
return 0;
}
QDataStream out(&file); // we will serialize the data into the file
out.setVersion(QDataStream::Qt_5_3); //adding this makes no difference
out << QString("the answer is"); // serialize a string
out << (qint32)42;
When I run this program, the file gets created in my desktop all right, but its size is 0 kB, it is blank. Naturally, when I then try this:
QFile file("/Users/kaustav/Desktop/boo.dat");
file.open(QIODevice::ReadOnly);
QDataStream in(&file); // read the data serialized from the file
in.setVersion(QDataStream::Qt_5_3);
QString str;
qint32 w;
in >> str >> w;
I get a blank string in str. What am I doing wrong? If of any help, I am using Qt Creator 3.1.1 based on Qt 5.2.1.
Check if there are any errors returned when calling open and ensure you close the file with file.close() when you're finished with it.
As you're using Qt 5, you should really use QSaveFile instead, when saving the data.
I am having some issues reading an online file. I'm trying to read what is in the file after it gets downloaded to a temporary file. Here is my code:
void MainWindow::fileIsReady( QNetworkReply * reply)
{
QTemporaryFile tmpFile;
tmpFile.write(reply->readAll());
QByteArray asdf = reply->readAll();
qDebug() (QString("%1").arg(asdf.length())); // returns 0
if (tmpFile.open())
{
qDebug << "attempting to read file";
QTextStream stream(&tmpFile);
QString value = stream.readAll();
qDebug << value; // value is returning nothing
}
else
{
qDebug() << "failed to open internet file";
}
}
// in MainWindow constructor (MainWindow::MainWindow)...
QNetworkAccessManager * manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(fileIsReady(QNetworkReply*)) );
manager->get(QNetworkRequest(QUrl("https://www.website.com/stuff/file.exe.md5")));
I'm going to be using this to compare two md5 strings.
There are several issues in your code:
You need to open tmpFile before writing to it.
reply->readAll() will return data only once. Further calls will return empty array. Once you received data using readAll, it's your responsibility to store it in a variable if you need it later.
After you wrote someting to file, the file pointer is at its end. You cannot read anything from it because there is no data there. You can use seek to move pointer to the beginning of the file and read its content.
There is no point in reading from file just after you wrote data to it. You can use QTextStream on QNetworkReply directly to read text from it. (Maybe this was just for debugging, I don't know.)
It's hard to believe that you need to create a temporary file just to calculate md5. There are simplier ways to do that.
So turns out I was dumb and forgot to open the reply first. Also, it was unnecessary for me to create a temp file. Here is my solution::
void MainWindow::fileIsReady( QNetworkReply * reply)
{
if (reply->error() == QNetworkReply::NoError)
{
if (reply->open(QIODevice::ReadOnly))
{
QByteArray asdf = reply->readAll();
qDebug() << (QString("asdf %1").arg(asdf.length()));
qDebug() << (QString(asdf));
}
else
{
qDebug << "cant open reply";
}
}
}
I am making a Qt application and I have a button to open a file, which is connected to a custom slot. This is the slot code so far:
void MainWindow::file_dialog() {
const QFileDialog *fd;
const QString filename = fd->getOpenFileName();
}
How could I have it then convert the file name to a const char *, open the file, read it and store the text in a QString, and then close the file. I am using Qt4.
To read the contents of a file, you can do this:
QString filename = QFileDialog::getOpenFileName();
QFile file(filename);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return;
QString content = file.readAll();
file.close();