Datei byteweise einlesen

Alles rund um die Programmierung mit Qt
Antworten
iaby
Beiträge: 53
Registriert: 10. Februar 2007 13:12

Datei byteweise einlesen

Beitrag 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
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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.
iaby
Beiträge: 53
Registriert: 10. Februar 2007 13:12

Beitrag 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();
        }
     }
gerome69
Beiträge: 188
Registriert: 28. April 2006 22:50
Wohnort: Berlin
Kontaktdaten:

Beitrag 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
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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.
gerome69
Beiträge: 188
Registriert: 28. April 2006 22:50
Wohnort: Berlin
Kontaktdaten:

Beitrag 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
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Es geht nicht darum, was in einen QString/QByteArray reinpasst (im normalfall 2GByte) sondern was man sinnvollerweise wirklich in den Speicher packt.
gerome69
Beiträge: 188
Registriert: 28. April 2006 22:50
Wohnort: Berlin
Kontaktdaten:

Beitrag 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.
iaby
Beiträge: 53
Registriert: 10. Februar 2007 13:12

Beitrag 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!
gerome69
Beiträge: 188
Registriert: 28. April 2006 22:50
Wohnort: Berlin
Kontaktdaten:

Beitrag 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
Antworten