Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 6

Qt-interest Archive, July 2007
inheriting QDataStream


Message 1 in thread

Hello,
I have xml file compressed with bzip2. I want my application to read data from 
this file. I think there are three solutions for this:
1) Decompress this file to temporary and parse it.
2) Inherit QTextStream to decompress data from the file, but I think it is 
impossible to decompress it by lines because the default block of bzip2 
compressed file is 900kb.
3) Inherit QDataStream to decompress the whole file to QString variable and 
then parse it.

Well, creating temporary file is not a good way, and I don't know how to 
implement the second way i described. So, I am trying the last one.

I want to create UnBZQDataStream class which inherits QDataStream, and create 
method "QString readDecompressedData()" which returns decompressed file.

So the question is: What is the right way to get data from a file in 
readDecompressedData() method?

Thanks in advance!

-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.


Message 2 in thread

Alex Fansky wrote:

> I have xml file compressed with bzip2. I want my application to read data
> from this file. I think there are three solutions for this:
> 1) Decompress this file to temporary and parse it.
> 2) Inherit QTextStream to decompress data from the file, but I think it is
> impossible to decompress it by lines because the default block of bzip2
> compressed file is 900kb.
> 3) Inherit QDataStream to decompress the whole file to QString variable
> and then parse it.
> 
> Well, creating temporary file is not a good way, and I don't know how to
> implement the second way i described. So, I am trying the last one.

You might also want to consider writing a custom I/O device:

  http://doc.trolltech.com/qq/qq12-iodevice.html

David
-- 
 [ signature omitted ] 

Message 3 in thread

Hello.

> 1) Decompress this file to temporary and parse it.
One of the best ways. You can do it with a single QProcess::execute()
call. The only requirement is to have bunzip2 installed which is not a
problem on Unix and you can always bundle one with your application on
Windows. Surely, it is not the fastest way, but will do for most cases.

> 2) Inherit QTextStream to decompress data from the file, but I think it is 
> impossible to decompress it by lines because the default block of bzip2 
> compressed file is 900kb.
> 3) Inherit QDataStream to decompress the whole file to QString variable and 
> then parse it.
Both seem to be wrong. QTextStream and QDataStream are just wrappers
over raw binary streams which are QIODevice subclasses. So you need to
inherit either QIODevice or QFile and create some QmyBzip2File. Then
just use QTextStream or whatever QtXml class over it, as you would do
with ordinary file, socket or whatever.

I would go for subclassing QFile and overriding readData() with call to
some bunzipping routine. Also it would be wise to override open and
give warning for trying to use QIODevice::Unbuffered flag, since it
would not make any sense for compressed data - you need to buffer it in
order to decompress it, I believe. Oh, and you should also override
isSequential() to return true, since you usually do not want to support
seeking unless you wish to do some crazy buffering for it, but that
would eventually lead to temporarily uncompressing the whole file again.

> I want to create UnBZQDataStream class which inherits QDataStream, and create 
> method "QString readDecompressedData()" which returns decompressed file.
Certainly this does not belong to QDataStream subclass. It would, if
your compressed data were just a part of more complicated binary format,
so you could do something like:
hdr = doc.readHeader();
if (hdr.getType() == Doc::XmlType) {
  body = doc.readXml();
}
but that would be generally unwise. It is both more efficient and
simpler to compress the whole file.

> So the question is: What is the right way to get data from a file in 
> readDecompressedData() method?
Well, again, you can use QProcess to start bzcat and to read data from
its stdout. Well, you do not even need to subclass QIODevice nor QFile
for it, since QProcess already does it for you. This is a kind of a Unix
way to go.

If you do not want to spawn external process for some reason, then it
is probably best to use libbzip2. Never did it though.

I had done something like this with zip, though:
http://quazip.sourceforge.net/
I believe bzip2 should be easier since you can only have one file within
it, so one class should be enough.

--
 [ signature omitted ] 

Message 4 in thread

Thanks for your reply and your explaining this simple things to me :)
Quazip is a very good example for me, because I am going to inherit QIODevice.

 
Ð ÑÐÐÐÑÐÐÐÐ ÐÑ Thursday 26 July 2007 22:27:03 Sergey A. Tachenov ÐÐÐÐÑÐÐ(Ð):
> Hello.
>
> > 1) Decompress this file to temporary and parse it.
>
> One of the best ways. You can do it with a single QProcess::execute()
> call. The only requirement is to have bunzip2 installed which is not a
> problem on Unix and you can always bundle one with your application on
> Windows. Surely, it is not the fastest way, but will do for most cases.
>
> > 2) Inherit QTextStream to decompress data from the file, but I think it
> > is impossible to decompress it by lines because the default block of
> > bzip2 compressed file is 900kb.
> > 3) Inherit QDataStream to decompress the whole file to QString variable
> > and then parse it.
>
> Both seem to be wrong. QTextStream and QDataStream are just wrappers
> over raw binary streams which are QIODevice subclasses. So you need to
> inherit either QIODevice or QFile and create some QmyBzip2File. Then
> just use QTextStream or whatever QtXml class over it, as you would do
> with ordinary file, socket or whatever.
>
> I would go for subclassing QFile and overriding readData() with call to
> some bunzipping routine. Also it would be wise to override open and
> give warning for trying to use QIODevice::Unbuffered flag, since it
> would not make any sense for compressed data - you need to buffer it in
> order to decompress it, I believe. Oh, and you should also override
> isSequential() to return true, since you usually do not want to support
> seeking unless you wish to do some crazy buffering for it, but that
> would eventually lead to temporarily uncompressing the whole file again.
>
> > I want to create UnBZQDataStream class which inherits QDataStream, and
> > create method "QString readDecompressedData()" which returns decompressed
> > file.
>
> Certainly this does not belong to QDataStream subclass. It would, if
> your compressed data were just a part of more complicated binary format,
> so you could do something like:
> hdr = doc.readHeader();
> if (hdr.getType() == Doc::XmlType) {
>   body = doc.readXml();
> }
> but that would be generally unwise. It is both more efficient and
> simpler to compress the whole file.
>
> > So the question is: What is the right way to get data from a file in
> > readDecompressedData() method?
>
> Well, again, you can use QProcess to start bzcat and to read data from
> its stdout. Well, you do not even need to subclass QIODevice nor QFile
> for it, since QProcess already does it for you. This is a kind of a Unix
> way to go.
>
> If you do not want to spawn external process for some reason, then it
> is probably best to use libbzip2. Never did it though.
>
> I had done something like this with zip, though:
> http://quazip.sourceforge.net/
> I believe bzip2 should be easier since you can only have one file within
> it, so one class should be enough.
>
> --
> Sergey A. Tachenov (AKA Alqualos) <laerel@xxxxxxxxx>
> Mission Control Centre (Moscow), Telemetry Service
> URL http://brededor.narod.ru/
> LJ-Zombie http://ayao.livejournal.com/
> ICQ UIN 135431139
>
> --


-- 
 [ signature omitted ] 

Attachment: signature.asc
Description: This is a digitally signed message part.