Encode/decode to binary file
-
@Hollywood33 said in Encode/decode to binary file:
It has to work with all file extensions and file sizes.
What does it have to do with file extension and file size?!
If I understood you correctly all you want to do is writing a text file containing 0 and 1 as characters, right?
File extension is simply part of file name and does not define its format. You could store a picture as "mypicture.xml" - it still would be a picture and not XML.
If you would have checked the documentation (http://doc.qt.io/qt-5/qfile.html) you would have found this:QFile file("out.txt"); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out(&file); out << "The magic number is: " << 49 << "\n";
-
Hi
I read it as he just want a binary file but do not understand that
some editors will not show the raw binary but show
it translated. So not sure he wants ASCII 0 and 1 but meant
it as a way to say binary which QDataStream already is :) -
@mrjj @Hollywood33 OK, then I would suggest to use a hex-editor instead of a text editor :-)
-
@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 :)