Seite 1 von 1
rec.field(i).value().toByteArray()
Verfasst: 8. August 2007 12:27
von Xander77
Hallo,
ich fülle in Access (per VBA) ein Feld in einer SQL Server-Datenbank mit binären Daten (4534 Bytes). Nun möchte ich mittels eines C++-Programms die Daten wieder auslesen und in eine Datei schreiben.
Der Aufruf rec.field(i).value().toByteArray() liefert mir zwar ein QByteArray-Objekt, dieses ist jedoch plötzlich 9068 Bytes groß (=2 x 4534 Bytes)!
(rec = QSqlRecord-Objekt)
Ich schaffe es einfach nicht, die ursprünglichen Daten aus diesem Byte-Array wiederherzustellen. Es scheinen auch einzelne Bytes plötzlich verändert worden zu sein (habe das Byte-Array über ein QDataStream in eine Datei geschrieben und diese mittels WinDiff mit der Originaldatei verglichen)!
Woran kann das liegen bzw. was mache ich falsch???
Verfasst: 8. August 2007 12:53
von upsala
In der Datenbank steht schon das drinne, was du meinst reingeschrieben zu haben?
Außerdem gibt QDataStream die Daten nicht 1:1 weiter, sondern hängt einen kleinen Header davor. (s. Doku)
Verfasst: 8. August 2007 13:05
von Xander77
Ich kann die Datei zumindest in VBA korrekt wiederherstellen, ohne irgendwelche Bytes zu ignorieren oder so! Das mit den Headerinformationen bei QDataStream muss ich mal genau nachlesen. Vielen Dank für den Tipp! Aber das erklärt doch noch immer nicht, weshalb das Byte-Array plötzlich doppelt so groß ist!
Verfasst: 8. August 2007 13:23
von Christian81
Ggf. werden die Daten als String interpretiert? Dann würde die Byteanzahl passen.
Verfasst: 8. August 2007 13:39
von Xander77
Was heißt als String interpretiert??? Wieso würde dann die Bytezahl stimmen??? Wüsste nicht, dass sich Bytes beim Interpretieren als String verdoppeln!?
Es kann ja wohl auch nicht sein, dass wenn ich extra ein QByteArray verwende, die Daten dann doch als String interpretiert werden! Dann kann man das auch lassen! Wenn ich das richtig gesehen habe, enthält das Byte-Array sowieso auch 0-Bytes, d.h. in dem Fall würden eher Bytes fehlen, anstatt zu viele da sein, da \0 ja das Ende eines Strings markiert.
Sorry, oder lieg ich jetzt völlig falsch???
Verfasst: 8. August 2007 13:43
von Christian81
Ich würde noch ein paar mehr Fragezeichen verwenden...
Was für einen Datentyp hat das Feld in der DB?
Verfasst: 8. August 2007 13:46
von Xander77
Der Datentyp des Feldes ist IMAGE (SQL Server 2000).
Verfasst: 8. August 2007 13:53
von Christian81
Ok, und was sagt
QVariant::Type QSqlField::type () const ?
Meine Vermutung ist einfach das Qt (oder wer auch immer da noch alles mitmischt) den Datentyp nicht korrekt erkennt.
Verfasst: 8. August 2007 13:57
von Xander77
Doch, das wird meiner Meinung nach richtig erkannt. Es handelt sich hierbei nur um einen Teil der Dateninterpretation einer Abfrage, der nur greift, wenn rec.field(i).type() den Wert QVariant::Type::ByteArray liefert. Daran sollte es also auch nicht liegen, oder?
Fast geschafft!
Verfasst: 8. August 2007 15:13
von Xander77
Ich bin jetzt einfach mal hingegangen und habe jedes zweite Byte aus dem Array gelöscht, bevor ich das Array in die Datei geschrieben habe. Dadurch haben dann nur noch einzelne Zeichen nicht übereingestimmt. Dann habe ich jetzt ein QTextStream statt eines QDataStreams verwendet und siehe da, das ICON (das ich als Testobjekt verwende) wird zumindest als solches erkannt, es gehen aber noch Farbinformationen verloren, da einige einzelne Bytes noch immer nicht korrekt wiedergegeben werden. Ich habe schon mit allen erdenklichen Codecs experimentiert, kein Erfolg! Die betroffenen Bytes werden in der Quelldatei als schwrzes Kästchen angezeigt. In der neu erzeugten Datei sind da dubiose ASCII-Symbole.
Kann mir aufgrund dieser Erkenntnisse noch jemand weiterhelfen?
Verfasst: 8. August 2007 15:24
von Christian81
Für Binärdaten verwendet man weder QText noch QDatastream (vor allem nicht wenn sie schon als QByteArray vorliegen) sondern einfach nur QIODevice::write(). QTextStream zerstört dir auf alle Fälle irgendwelche Zeichen.
Verfasst: 8. August 2007 15:38
von Xander77
Danke, gut zu wissen!
Ich mache jetzt also folgendes:
QFile file(path);
if (file.open(QIODevice::WriteOnly)) {
file.write(bytes);
file.close();
}
Es werden allerdings immernoch einzelne Zeichen "verkorkst".
Im Anhang hab ich mal die neu erzeugte Datei und die Originaldatein beigefügt (Extension ist eigentlich ICO; ist aber hier verboten).
Ursache gefunden
Verfasst: 9. August 2007 12:01
von Xander77
Ich habe die Ursache inzwischen gefunden. Das Problem lag doch nicht beim C++-Programm, sondern wie auch zuerst vermutet beim Schreiben der Daten im Access-Frontend!
Trotzdem vielen Dank nochmals an alle!
