Speicherlimit von Stringvariablen

07/02/2010 - 13:12 von Paul Pierot | Report spam
Hallo,

ich habe ein Anfàngerproblemchen.

Ich möchte eine Datei in einem Datenbankfeld (DAO), mit Type=dbMemo
abspeichern.

Dazu lese ich die Datei in eine Stringvariable binàr ein und übertrage
sie in meine Datenbank:

Dim sInhalt$, F%

F = FreeFile
Open "C:\test.zip" For Binary As #F
sInhalt = Space$(LOF(F))
Get #F, , sInhalt ' <-- hier der Fehler 7
Close #F
Tabelle("Inhalt") = sInhalt

Das geht gut.
Ab einer bestimmten Dateigröße (ca. 80MB) macht aber meine
Stringvariable sInhalt nicht mehr mit: "Fehler 7: Nicht genügend
Speicher"
Laut Hilfe können Zeichenfolgen variabler Lànge bis zu 2 Milliarden
Zeichen enthalten, das Limit liegt also doch viel höher? Wie kommt das?
Und gibt es da eine unlimitierte Lösung?

Danke.
Einen Gruß von
Paul Pierot
 

Lesen sie die antworten

#1 Thorsten Albers
07/02/2010 - 14:23 | Warnen spam
Paul Pierot schrieb im Beitrag
<1xedhs696o32a$.1hzj18xmhh9aq$...
Ich möchte eine Datei in einem Datenbankfeld (DAO), mit Type=dbMemo
abspeichern.
Dazu lese ich die Datei in eine Stringvariable binàr ein und übertrage
sie in meine Datenbank:

Dim sInhalt$, F%

F = FreeFile
Open "C:\test.zip" For Binary As #F
sInhalt = Space$(LOF(F))
Get #F, , sInhalt ' <-- hier der Fehler 7
Close #F
Tabelle("Inhalt") = sInhalt

Das geht gut.
Ab einer bestimmten Dateigröße (ca. 80MB) macht aber meine
Stringvariable sInhalt nicht mehr mit: "Fehler 7: Nicht genügend
Speicher"
Laut Hilfe können Zeichenfolgen variabler Lànge bis zu 2 Milliarden
Zeichen enthalten, das Limit liegt also doch viel höher? Wie kommt das?
Und gibt es da eine unlimitierte Lösung?



Da ein String in VB als Unicode-String mit 2 Bytes pro Zeichen gespeichert
wird, benötigt Dein String mit '80 MB' tatsàchlich 160 MB Speicher.
Wird der String 'sInhalt' hier an Get übergeben, wandelt VB ihn intern
zunàchst in einen ANSI-String um, liest dann den Dateiinhalt in den String
und wandelt ihn dann intern anschließend wieder in einen Unicode-String um.
Dabei bleibt aber der Inhalt von 'sInhalt' solange bestehen, bis der
endgültige Unicode-String erstellt wurde und in 'sInhalt' platziert werden
kann, d.h. kurzfristig werden 160 MB + 80 MB + 160 MB = 400 MB benötigt.

Umgehen kannst Du das, indem Du ein Byte-Array verwendest.

"2 Milliarde Zeichen" als max. Lànge eines Strings sind eine sehr
theoretische Angabe in der VB-Online-Hilfe. Tatsàchlich stehen jedem Prozeß
4 GB an virtuellem Speicher zur Verfügung, der aber für alle Codes und
Daten des Prozesses reichen muß. Bei einem Prozess, der eine
MS-Datenbank-Maschine verwendet, müssen etliche DLLs, die zu der
Datenbank-Maschine gehören, als Code in den virtuellen Speicher gemappt
werden, zudem haben einige dieser DLLs offenbar auch noch einen recht hohen
Speicherbedarf für Daten, so daß bei einer Datenbank-Anwendung unter VB
immer von relativ wenig Speicher ausgegangen werden muß.

Entscheidend kommt aber hinzu, daß jede Speicherreservierung und -freigabe
zu einer Fragmentierung des Speichers führen kann, d.h. der freie Speicher
steht nicht mehr in einem Stück sondern in vielen kleineren Blöcken zur
Verfügung. Bei einer Speicherreservierung von virtuellem Speicher muß der
angeforderte Speicher als ein zusammenhàngender Block reservierbar sein,
sonst schlàgt die Reservierung - wie bei Dir - fehl.

Das làßt sich nicht àndern, und der einzige Weg das zu umgehen ist, derart
umfangreiche Daten nie im ganzen in den Speicher einzulesen.

Wie Du das nun im Zusammenhang mit Deiner Datenbank hinbekommst, erfàhrst
Du am besten von Datenbankprofis, die Du allerdings nicht in dieser
Newsgroup ansprechen solltest, sondern in der eigens für Datenbankfragen
mit VB <= 6 eingerichteten Newsgroup

microsoft.public.de.vb.datenbank

Thorsten Albers

albers (a) uni-freiburg.de

Ähnliche fragen