Seite 1 von 1

Binärdaten suchen [Erledigt]

Verfasst: Di, 05. Mai 2015 21:17
von Jan
Hallo,

ich habe eine FOXCDX mit einem V-Feld (binäres Memofeld). Da speichere ich Bilder drin, meist als jpg, aber auch als bmp, teilweise auch mal pdf. Da ich sicherstellen möchte, das jedes Bild nur 1x darin gespeichert wird schaue ich vor jedem Speichern nach, ob das schon existiert. Aber egal ob ich das mit einem Vergleich Feldinhalt - Variableninhalt in einer Do-While-Schleife mache, oder per DbLocate() - die vorhandenen Bilder werden niemals gefunden.

Liegt das daran, daß das Binärdaten sind?

Aber egal warum - wie kann ich die Bilder finden?

Jan

Re: Binärdaten suchen

Verfasst: Di, 05. Mai 2015 23:11
von Martin Altmann
Moin Jan,
es gibt eigentlich nur eine sinnvolle Methode:
Ermittele vor dem Ablegen einer jeden Binärdatei in dem Memofeld ihre Quersumme (als Datei im Dateisystem!!!) und speichere diese in einem gesonderten Feld. Dann kannst Du zum Suchen, ob der Eintrag schon vorhanden ist, nach der Quersumme suchen.
Dir muss aber klar sein, dass optisch identische Bilder unterschiedliche Quersummen haben können (unterschiedliche Helligkeit/Schärfe/eines ist leicht beschnitten/...)

Viele Grüße,
Martin

Re: Binärdaten suchen

Verfasst: Mi, 06. Mai 2015 2:42
von AUGE_OHR
Martin Altmann hat geschrieben:es gibt eigentlich nur eine sinnvolle Methode:
was nicht geht ist

Code: Alles auswählen

      IF ::oBMP1 = ::oBMP2
         Msgbox("::oBMP1 = ::oBMP2")
      ENDIF
oder
      IF ::oBild1:Caption = ::oBild2:Caption
         Msgbox("::oBild1 = ::oBild2")
      ENDIF
wobei ja Objecte verglichen werden.
was aber funktioniert ist

Code: Alles auswählen

LOCAL aFiles := Directory("d:\Bilder\*.JPG")
LOCAL iMax   := Len(aFiles)
LOCAL i
LOCAL a,b

   a := ::oBMP1:SetBuffer()
   FOR i := 1 TO iMax
      ::oBMP2 := XbpBitmap():new():create()
      ::oBMP2:loadfile("d:\Bilder\"+aFiles[i][1])

      b := ::oBMP2:SetBuffer()
      IF a = b
         Msgbox("a = b")
         EXIT
      ENDIF
   NEXT

Re: Binärdaten suchen

Verfasst: Mi, 06. Mai 2015 11:25
von brandelh
länge von Indexbegriffen ist begrenzt. Ein MD5 ist z.B. ein eindeutiger Schlüssel der immer 32 Byte lang ist ...

Re: Binärdaten suchen

Verfasst: Mi, 06. Mai 2015 11:51
von georg
Hallo,


also, ein MD5 Hash alleine ist NICHT EINDEUTIG. Er wird es, wenn man ihn mit der Länge der Originals (ob nun String oder Datei) verbindet. Diese Kombination ist mit hoher Wahrscheinlichkeit eindeutig.

Mehr zum Thema MD5 hier: http://de.wikipedia.org/wiki/Message-Digest_Algorithm_5

Re: Binärdaten suchen

Verfasst: Mi, 06. Mai 2015 11:53
von Jan
Moin,

Danke für Eure Gedanken dazu. Nur um das richtig zu stellen:
  • Es gibt keinen Index auf das Feld. Würde auch keinen Sinn machen aus verschiedenen Gründen.
  • Ich habe keine Objekte oder Dateien, nur Strings oder Feldinhalte.
  • Es geht eindeutig immer um das exakte Bild. Variationen davon würde ich als unterschiedliche Bilder ansehen und dann auch getrennt speichern.
Jan

Re: Binärdaten suchen

Verfasst: Mi, 06. Mai 2015 12:34
von georg
Hallo, Jan -


ein denkbares Vorgehen wäre - um die Vorschläge mal zu bündeln - je Zeichenkette den MD5 zu ermitteln und diesen zusammen mit der Länge der Zeichenkette in der Datei zu speichern. Dann könntest Du (falls diese Option gegeben ist), einen Index über das MD5 und das Längenfeld legen und hättest darüber eine schnelle Kontrolle, ob identische Daten vorhanden sind.

Findest Du eine Übereinstimmung, kannst Du (wenn gewünscht) die beiden Zeichenketten in einer Schleife Byte für Byte vergleichen, um eine letzte Gewissheit zu haben.

Das sollte eigentlich der schnellste Weg sein.

Als Alternative kannst Du die Datei natürlich durchlesen und Länge bzw. MD5 für jeden Satz vergleichen.

Re: Binärdaten suchen

Verfasst: Mi, 06. Mai 2015 14:43
von brandelh
besser ... kombiniere beides zum eindeutigen MD5 und speichere diesen ...
MD5 auf Datei => 32 byte + str(len(datei),18) => darauf nochmal MD5 => diesen speichern und auch nach diesem suchen ... in Datei nur 32 Byte, mit index ODER dbLocate ...

Re: Binärdaten suchen

Verfasst: Do, 07. Mai 2015 7:11
von Jan
Hallo,

so, ich hab das jetzt mal so versucht:

Code: Alles auswählen

                 bBild := LoadFromUrl(aMemories[i][6])                                             // Bild herunterladen

                 cHash := Char2Hash(bBild)
                 nLaenge := Len(bBild)

                 DO WHILE .NOT. bilder->(EoF())
                    IF Char2Hash(bilder->bild) == cHash .AND. Len(bilder->bild) == nLaenge
                       Exit
                    ENDIF
                    bilder->(DbSkip())
                 ENDDO
Das funktioneirt nach ersten Tests einwandfrei. Und auch schnell. Wobei ich trotzdem überlege, eventuell ein Feld für den cHash anzulegen.

Die Frage für mich ist aber immer noch, warum binärdaten nicht direkt gefunden werden können. Egal ob über einen Vergleich oder über DbLocate().

Jan

Re: Binärdaten suchen [Erledigt]

Verfasst: Do, 07. Mai 2015 7:19
von brandelh
wie sah den der suchcode aus ?
zumindest field->bild == cBildBuffer sollten identisch sein ... wenn field->bild := cBildBuffer aufgerufen wurde.
Möglich wäre, dass der Vergleich eine hohe Längenbegrenzung hat, die wir normalerweise nicht erreichen.

Wo hast du die Funktion Char2Hash(bBild) her ?

Re: Binärdaten suchen [Erledigt]

Verfasst: Do, 07. Mai 2015 7:37
von Jan
Hallo Hubert,

Char2Hash() ist eine Standard-Xbase++-Funktion.

Und field->bild == cBildBuffer hat ja eben leider nicht funktioniert. Das war ja das Problem.

Jan

Re: Binärdaten suchen [Erledigt]

Verfasst: Do, 07. Mai 2015 10:31
von brandelh
woher weißt du dann, dass der Inhalt wirklich noch gleich ist :?:

wie lädst du die datei ? memoread ist möglicherweise schuld, OEM / Ansi Umwandlung ?

Re: Binärdaten suchen [Erledigt]

Verfasst: Do, 07. Mai 2015 11:20
von Jan
Hallo Hubert,

die Datei wird per LoadFromUrl() aus dem Internet geladen, und direkt ohne jede Umwandlung in dem V-Memo-Feld gespeichert.

Jan

Re: Binärdaten suchen [Erledigt]

Verfasst: Do, 07. Mai 2015 11:50
von brandelh
dann speichere die Datei dazwischen auf die Festpatte (t1.bin),
schreibe in v feld, lese in neue var und speichere in datei t2.bin ...
wenn

Code: Alles auswählen

comp t1 t2
keinen unterschied findet, ist alles ok ... wenn nicht ;-)

Nur so kannst du sicher sein, dass die Daten OK sind ... JPG ? dann noch mit paint öffnen ...
Möglicherweise werden aus dem V Feld Füllbytes angehängt.

PS: ich meine ich hätte schon 600 MB Strings miteinander verglichen , das ging ...

Re: Binärdaten suchen [Erledigt]

Verfasst: Do, 07. Mai 2015 12:04
von Jan
Hallo Hubert,

die Daten werden meiner Meinung nach korrekt gespeichert. Ich schreibe die Inhalte der V-Memo-Felder teilweise wieder auf die Platte, die sind 1a.

Abgesehen davon sind ja der Hash und die Lenge von Feldinhalt und Internet-String gleich. Also sollten Feldinhalt und String sehr wahrscheinlich auch identisch sein.

Jan

Re: Binärdaten suchen [Erledigt]

Verfasst: Do, 07. Mai 2015 12:20
von Tom
Der Vergleich von SHA1-Hashes sollte meistens funktionieren. Es ist zwar denkbar, dass unterschiedliche Daten gleiche Hashes (die immer nur 40 Zeichen lang sind!) produzieren, aber nicht eben wahrscheinlich. Eine Alternative wäre die Konvertierung der Binärdaten z.B. mit Str2Hex(), dann könnte man auch direkt und verlustfrei vergleichen - und müsste nicht immerzu umrechnen (nur bei der Anzeige der Bilder).

Re: Binärdaten suchen [Erledigt]

Verfasst: Do, 07. Mai 2015 13:33
von brandelh
Jan hat geschrieben:die Daten werden meiner Meinung nach korrekt gespeichert.
Ich schreibe die Inhalte der V-Memo-Felder teilweise wieder auf die Platte, die sind 1a.
Abgesehen davon sind ja der Hash und die Lenge von Feldinhalt und Internet-String gleich.
ich wollte nur darauf hinweisen dies zu prüfen ;-)