3

I want to write a QString in a textfile in a ziparchive with QuaZip. I use Qt Creator on WinXP. With my code the text-file in the archive is created but empty.

QDomDocument doc;
/* doc is filled with some XML-data */

zipfile = new QuaZip("test.zip");
zipfile->open(QuaZip::mdCreate);
QuaZipFile file(zipfile);
file.open(QIODevice::WriteOnly, QuaZipNewInfo("foo.xml"));

QTextStream ts ( &file );
ts << doc.toString();

file.close();
zipfile.close();

When I try with a QFile it works as expected:

QDomDocument doc;
/* doc is filled with some XML-data */

QFile file("test.xml");
file.open(QIODevice::WriteOnly);

QTextStream ts ( &file );
ts << doc.toString();

file.close();

I find the right content in test.xml, so the String is there, but somehow the QTextStream doesn't want to work with the QuaZipFile.

When I do it with a QDataStream instead of QTextStream there is an output, but not a correct one. QDomDocument doc; /* doc is filled with some XML-data */

zipfile = new QuaZip("test.zip");
zipfile->open(QuaZip::mdCreate);
QuaZipFile file(zipfile);
file.open(QIODevice::WriteOnly, QuaZipNewInfo("foo.xml"));

QDataStream ts ( &file );
ts << doc.toString();

file.close();
zipfile.close();

The foo.xml in the test.zip is filled with some data, but wrong formatted (between each character is an extra 'nul'-character).

How can I write the String in the textfile in the zip-archive?

Thanks, Paul

Charles
  • 50,943
  • 13
  • 104
  • 142
cad
  • 347
  • 5
  • 20
  • Seems like the text is UTF-16 encoded. – leemes Jul 13 '12 at 13:29
  • That worked, a bit at least. I changed it to `QDataStream ts(&file); ts << doc.toString().toUtf8;` and I get a correct file, except in the beginning: the first 4 chars are `00 00 00 61`. I found out, this is the length of the file, so after this "header" there are 0x61 more chars. This header is not part of the string I pass to the QDataStream, so I cannot cut it off with .mid(4) or something. Any idea? And if I use QTextStream, nothing is written, no matter what encoding I use (utf8, Latin1). Thanks for helping! – cad Jul 13 '12 at 16:50
  • This is the encoding of QDataStream. If you dont want this header, simply dont use QDataStream. – leemes Jul 13 '12 at 17:08
  • Is there another possibility to write text in a QuaZipFile? QTextStream doesn't produce any output and QDataStream has this header I don't want. – cad Jul 13 '12 at 19:49
  • 1
    just try directly: `file.write(doc.toString().toUtf8());` So neither QTextStream, nor QDataStream... – leemes Jul 13 '12 at 20:40
  • Glad I could help! I made an answer from this comment. Please check if the code I posted is correct. Then I'd be pleased if you'd accept it :) – leemes Jul 13 '12 at 21:03

2 Answers2

4

You don't need QTextStream or QDataStream to write a QDomDocument to a ZIP file.

You can simply do the following:

QDomDocument doc;
/* doc is filled with some XML-data */

zipfile = new QuaZip("test.zip");
zipfile->open(QuaZip::mdCreate);
QuaZipFile file(zipfile);
file.open(QIODevice::WriteOnly, QuaZipNewInfo("foo.xml"));

// After .toString(), you should specify a text codec to use to encode the
// string data into the (binary) file. Here, I use UTF-8:
file.write(doc.toString().toUtf8());

file.close();
zipfile->close();
leemes
  • 44,967
  • 21
  • 135
  • 183
  • 1
    When I use that code, the compiler tells me the following message: "QuaZip::setCurrentFile(): ZIP is not open in mdUnzip mode". It still writes the data, but is annoying. Do you know how to fix it? - I also have the problem that the file that I want to change and that I set with "zip.setCurrentFile(jsonName)" gets correctly updated, but the other files that the zip contains get deleted (overwritten, I guess). Any clue about this? – AlvaroSantisteban Dec 18 '12 at 10:37
  • I still got the message, but at least I solved the other problem. I had to use "zipfile->open(QuaZip::mdAdd)", which is a very bad name to say that you want to override something... – AlvaroSantisteban Dec 18 '12 at 14:10
  • @leemes yea i know but seeing as i found this post when trying to solve a similar issue just figured some people might find it too and not know about pointer logic and be sitting there facepalming when it doesnt work :) – AngryDuck May 17 '13 at 08:08
3

In the original first example you must flush the stream:

QDomDocument doc;
/* doc is filled with some XML-data */

zipfile = new QuaZip("test.zip");
zipfile->open(QuaZip::mdCreate);
QuaZipFile file(zipfile);
file.open(QIODevice::WriteOnly, QuaZipNewInfo("foo.xml"));

QTextStream ts ( &file );
ts << doc.toString();
ts.flush();

file.close();
zipfile.close();