Encode/decode to binary file
-
@Hollywood33 Then you want to write text. Because text editors (like the name suggests) only understand text. It wouldn't be a binary file. You would write 1 and 0 as characters:
QFile file("out.txt"); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out(&file); out << "010001100101110";
You need to understand the difference between text and binary. 0 as character in a text file is stored as ASCII number 48, 1 is 49. That means if you store 01 in a text file and open it in a hex editor you will see 4849 (or 0x30 0x31 as hex).
-
@Hollywood33 '1' and '0' are same in ASCII and UTF-8 as far as I know...
-
because I'm a good guy :-)
QString toBitString(const QVariant &v) { QByteArray bytes = v.toByteArray(); QString bitString; QChar Zero('0'); QChar One('1'); for(int y(0); y <bytes.size(); y++){ for(int i(0); i < 8; i++){ bool b = (bytes[y] >> i) & 1; bitString.append(b ? One:Zero); } } return bitString; }
Edit:
Small edit in the code example,v.toByteArray().data()
totally unnecessary! -
@Hollywood33
Hi
The docs shows how to use it.
http://doc.qt.io/qt-5/qfiledialog.html
It has sample :) -
Ok, here is the code how I would save it with
QFileDialog
class using @J-Hilk solution.QString filters = "Text Documents (*.txt);;All files (*.*)"; QString filePath = QFileDialog::getSaveFileName(this, "Save binary file", qApp->applicationDirPath() + "/MyFile", filters, nullptr); if (!filePath.isEmpty()) { QFile *myFile = new QFile(filePath); myFile->open(QIODevice::WriteOnly); QTextStream myTextStream(myFile); //QTextStream is used because you want to save it in .txt file myTextStream << toBitString(QString("This is a test!")); myFile->close(); myFile->deleteLater(); QMessageBox::information(this, "Information", "Binary file is saved!", QMessageBox::Ok); }
-
@Cobra91151
Hi
Just as a note.
There is really no need to new the QFile.
QFile myFile;
will work just as fine as it has no need to survive the scope/function.
but you do delete it so no leak but no real benefit :) -
@Cobra91151 can't build: nullptr is not declared in this scope;
tobitstring is not declared in this scope -
@Hollywood33
odd it dont know nullptr but you can use 0 (zero) or NULL instead
also just remove
myTextStream << toBitString(QString("This is a test!"));
--->
myTextStream << QString("This is a test!"); -
You must declare
tobitstring
function in the header (.h
file) to use it. + Specify more info about your building process (Qt version, compiler, OS)?Also, instead of
nullptr
, you can use -Q_NULLPTR
macro or add theQString *selectedFilter
as the parameter points to in the docs - QFileDialog. -
@mrjj it writes test text, no 0&1s.
I was told to read into QByteArray and then send it to stream:
QFile f("/Users/ro888.jpg");
f.open(QIODevice::ReadOnly);
QByteArray ba = f.readAll();
stream << ba;So I have to update code in the following example using QByteArray:
How to do it?void MainWindow::on_pushButton_3_clicked()
{
QFile file("/Users/file.bin");
if(file.open(QIODevice::WriteOnly))
{
QDataStream stream(&file);
stream. setVersion(QDataStream::Qt_4_2);
stream << QPointF(30, 30) << QImage("/Users/ro888.jpg");
if(stream.status() != QDataStream::Ok)
{
qDebug() << "Error";
}
}
file.close();
} -
@Hollywood33
Hi
Yes sorry my bad.
I missed that QString toBitString(const QVariant &v) was the function @J-Hilk provided :)
So place
QString toBitString(const QVariant &v) in .h and
the body in the cpp as @Cobra91151 says :) -
@Hollywood33
Hi
Yes using QDataStream will be a binary file.
You paths for the JPG files looks a bit odd but if you are sure they are valid then
should produce a truly binary file :) -
@Cobra91151 I'm on Qt 5.1.0, OS X 10.6.8
I added to header #include "tobitstring.h" - error: no such file or directory -
@Hollywood33 said in Encode/decode to binary file:
@Cobra91151 I'm on Qt 5.1.0, OS X 10.6.8
I added to header #include "tobitstring.h" - error: no such file or directoryYou should add the prototype of the function to header file, not include it. Include works for additional files, not for functions!
For example:
test.h
file:public: explicit Test(QWidget *parent = 0); QString toBitString(const QVariant &v); ~Test();
It contains a constructor, prototype function and destructor.
And then put the body of the function intest.cpp
file like this:QString Test::toBitString(const QVariant &v) { QByteArray bytes = v.toByteArray(); QString bitString = ""; QChar Zero('0'); QChar One('1'); for (int y(0); y <bytes.size(); y++){ for (int i(0); i < 8; i++){ bool b = (bytes[y] >> i) & 1; bitString.append(b ? One:Zero); } } return bitString; }
Your class is -
MainWindow
,Test
is just for testing purposes. -
@Cobra91151 I have to compliment your patience. *Thumbs up*