Seite 1 von 1

Datei byteweise einlesen

Verfasst: 21. Februar 2008 11:28
von iaby
Hallo zusammen!

Ich will eine Datei byteweise einlesen und jedes dieser Bytes auf gesetzte Bits 0 bis 7 überprüfen!
Hier mein Code-Ausschnitt:

Code: Alles auswählen

    QFile inFile(app.arguments().at(1));
    if (!inFile.open(QIODevice::ReadOnly)) {
        qDebug("Could not open input file!");
        return 1;
    }

    QTextStream inStream(&inFile);

    while (!inStream.atEnd()) {
        QString inString = inStream.read(1);
        unsigned char inChar = inString[0].cell();
        for (unsigned char i = 0; i < 8; i++) {
             if ((inChar & (0x01 << i)) != 0)
                 doSomething();
         }
    }
Leider ist hier das MSB jedes Bytes fast immer 0, was eigentlich nicht sein kann! Auch bei ausführbaren Dateien oder sogar /dev/urandom ist dies so!
Hat dies was mit den Spracheinstellungen zu tun, also mit dem ASCII Zeichensatz oder sonst was?

Gruß,
iaby

Verfasst: 21. Februar 2008 11:37
von upsala
Warum gehst du eigentlich über QTextStream, ich würde direkt vom QIODevice lesen. Mal davon abgesehen, daß du 'binär' arbeiten willst, aber QTextStream konvertieren darf/kann.

Verfasst: 21. Februar 2008 11:49
von iaby
Vielen Dank!
Hatte bis jetzt nur mit TextStream gearbeitet aber jetzt ist mir das ganze viel klarer geworden!

Code sieht jetzt so aus und funktioniert auch einwandfrei:

Code: Alles auswählen

    QFile inFile(app.arguments().at(1));
    if (!inFile.open(QIODevice::ReadOnly)) {
        qDebug("Could not open input file!");
        return 1;
    }

     while (!inFile.atEnd()) {
        char inChar;
        inFile.getChar(&inChar);
        for (unsigned char i = 0; i < 8; i++) {
             if ((inChar & (0x01 << i)) != 0)
                 doSomething();
        }
     }

Verfasst: 21. Februar 2008 13:02
von gerome69
Die Methode readAll() von QFile holt dir auf einen Schlag alle Bytes in ein QByteArray.
Dürfte performanter sein als dein byteweises Lesen.

http://doc.trolltech.com/4.3/qiodevice.html#readAll

Gérôme

Verfasst: 21. Februar 2008 13:56
von upsala
Das kommt darauf an, ob intern ein Puffer verwendet wird, oder nicht. readAll kann auf jeden Fall gefährlich sein, wenn man nicht weis, wie groß eine Datei ist und eine zu große Datei eingelesen wird. Sollte QFile keinen int. Puffer verwenden, kann man das selbst lösen, indem man immer 1-16k Blöcke von QFile holt und diese dann auswertet.

Verfasst: 21. Februar 2008 18:27
von gerome69
upsala hat geschrieben:Das kommt darauf an, ob intern ein Puffer verwendet wird, oder nicht. readAll kann auf jeden Fall gefährlich sein, wenn man nicht weis, wie groß eine Datei ist und eine zu große Datei eingelesen wird. Sollte QFile keinen int. Puffer verwenden, kann man das selbst lösen, indem man immer 1-16k Blöcke von QFile holt und diese dann auswertet.
Ich habe mal einen Performancetest gemacht. Byteweise Einlesen ist kaum langsamer als readAll(), weil wie zu erwarten war, gepuffert wird (Win32 und Linux).

Zu große Datei? Na ja, ich einen QString kann man mehr als 1 GB packen, da gehe ich mal davon aus, daß ein QByteArray auch ähnliche Mengen aufnehmen kann.

Gruß, Gérôme

Verfasst: 21. Februar 2008 18:51
von upsala
Es geht nicht darum, was in einen QString/QByteArray reinpasst (im normalfall 2GByte) sondern was man sinnvollerweise wirklich in den Speicher packt.

Verfasst: 21. Februar 2008 19:05
von gerome69
upsala hat geschrieben:Es geht nicht darum, was in einen QString/QByteArray reinpasst (im normalfall 2GByte) sondern was man sinnvollerweise wirklich in den Speicher packt.
Da hast du natürlich recht, mehr als sagen wir 50 MB würde ich auch nicht in den Speicher laden wollen.

Aber ich denke, daß der OP nicht über Dateien solcher Größe sprach?!

G.

Verfasst: 21. Februar 2008 21:34
von iaby
Ja ich hab mir bei der Performance auch schon Gedanken gemacht, wobei das bei meinem Anwendungszweck sehr irrelevant ist.
Es ist nur ein sehr kleines Programm, welches eine Datei in ein Schwarz-Weiß Bild verwandelt. Ist zum Visualisieren von "Zufall" gedacht, so wir er von /dev/random geliefert wird.
Die Dateien sind also eher klein ( <1MB ) und zudem brauch ich das Programm ja auch nicht oft!

Verfasst: 22. Februar 2008 12:31
von gerome69
iaby hat geschrieben:Die Dateien sind also eher klein ( <1MB ) und zudem brauch ich das Programm ja auch nicht oft!
Dann würde ich doch auf jeden Fall .readAll() nehmen.

Gérôme