[VB] Binary files

Pagina: 1
Acties:

  • Priet
  • Registratie: Januari 2001
  • Laatst online: 30-08 20:04

Priet

To boldly do what no one has..

Topicstarter
Gegeven het volgende (hoe heet zo'n ding ook alweer :?) dinges:
Visual Basic:
1
2
3
4
5
6
Public Type Dictionary
  English As String
  Elven As String
End Type

Public Dict() As Dictionary

Dict() heeft de grootte van een paar duizend. Het wordt op de volgende manier weggeschreven naar een bestand:
Visual Basic:
1
2
3
4
5
Open strDicFile For Binary As #1
  For lngCounter = 1 To UBound(Dict)
    Put #1, , Dict(lngCounter)
  Next lngCounter
Close

Inlezen van het bestand gaat op deze manier:
Visual Basic:
1
2
3
4
5
6
7
Open strDicFile For Binary As #1
  While Not EOF(1)
    lngCounter = lngCounter + 1
    ReDim Preserve Dict(lngCounter)
    Get #1, , Dict(lngCounter)
  Wend
Close


Maar het lukt me maar niet om één (gewijzigde) record weg te schrijven. Bijvoorbeeld, Dict(135) heeft voor English en Elven andere waardes aangenomen. Hoe zorg ik er dan voor dat alleen deze Dict(135) wordt weggeschreven zodat de file weer up to date is? Als ik het op de volgende manier doet loopt de complete file in de soep :'(
Visual Basic:
1
2
3
4
5
  Dict(lngRecordNr).English = txtEnglish.Text
  Dict(lngRecordNr).Elven = txtElven.Text
  Open strDicFile For Binary As #1
    Put #1, , Dict(lngRecordNr)
  Close

En als ik het op een andere manier weg probeer te schrijven wordt er volgens mij helemaal niks weggeschreven :?
Visual Basic:
1
2
3
4
5
6
  Dict(lngRecordNr).English = txtEnglish.Text
  Dict(lngRecordNr).Elven = txtElven.Text
  Open strDicFile For Binary As #1
    Put #1, lngRecordNr, Dict(lngRecordNr).English
    Put #1, lngRecordNr, Dict(lngRecordNr).Elven
  Close


Suggesties?

"If you see a light at the end of a wormhole, it's probably a photon torpedo!"


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 28-08 17:06

Sponge

Serious Game Developer

Put #1 Cint(lngRecordNr), Dict(record)

misschien.

Overigens weet ik niet of het gaat lukken met variabele string lengthes.

Probeer eens voor de verandering:

code:
1
2
3
4
Public Type Dictionary
  English As String *20
  Elven As String *20
End Type


(alle woorden nu max 20 letters, en een "a" wordt "a<19 spaties>")

  • PrinsEdje80
  • Registratie: Oktober 2001
  • Laatst online: 01-01 15:26

PrinsEdje80

Holographic, not grated...

Vooropgesteld: ik heb geen verstand van VB, maar een beetje van programmeren. Is wat jij wilt niet onmogelijk? Nl. 1 stukje van je file wijzigen is wel mogelijk, maar wat daarna komt moet je weer helemaal opnieuw schrijven? Correct me if I am wrong.

Used to be Down Under... Foto gallery


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 28-08 17:06

Sponge

Serious Game Developer

Nee, met Put Kan je zelf zeggen welke positie begint.

Goh dit is zo lang gelden he, er meot nog iets veranderd worden.. nu schrijven we naar het id van de record, niet de groote in bytes. stom dat ik daar net neit aan gedacht heb

Probeer eens: Put #1, LenB(Dictionary) * lngRecordNr, dict

Toch denk ik dat die vaste string lengte ook belangrijk is.

Overigens herinner ik me iets van vroeger (lees 3 jaar geleden ofzo) dat luide

code:
1
2
Open x for binary as #1 LOF = 40 
'(of LOf(40))


Waarmee je de record grootte instelde oid.

Check anders nog ff: "Put Visual Basic" (oid) op msdn.microsoft.com

  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 11:07

johnwoo

3S-GTE

41.6C.6D.61.72 schreef op 15 oktober 2002 @ 09:47:
[...]
Toch denk ik dat die vaste string lengte ook belangrijk is.
[/...]
Voor files die For Binary zijn geopend wel ja; dan wordt alleen de data gelezen/geschreven, en LenB zal dan waarschijnlijk 0 teruggeven als de string leeg is. Je moet dus idd fixed length strings gebruiken.

Voor files die For Random zijn geopend kan je wel variable length strings gebruiken; dan wordt namelijk, behalve de data zelf, ook wat metadata weggeschreven. Voor strings wordt hun lengte voor de data zelf weggeschreven (en ook weer ingelezen):
If the variable being written is a variable-length string, Put writes a 2-byte descriptor containing the string length and then the variable. The record length specified by the Len clause in the Open statement must be at least 2 bytes greater than the actual length of the string.
Overigens is de tweede parameter bij Random files geen bytenumber maar recordnumber. Misschien is dit wel wat makkelijker in dit geval? :)

Get in MSDN, Put in MSDN
Voorbeeldje van Put met user-defined records en Random files (dit lijkt me precies wat in dit geval gezocht wordt :) )

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


Verwijderd

Suggesties?
Database

  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 28-08 17:06

Sponge

Serious Game Developer

johnwoo schreef op 15 oktober 2002 @ 11:31:
[...]


Overigens is de tweede parameter bij Random files geen bytenumber maar recordnumber. Misschien is dit wel wat makkelijker in dit geval? :)
_/-\o_ dat is 'em denk ik. De topic starter zal dat kunnen gebruiken voor zijn probleem. Ik gebruik random al jaren niet meer. Voor die random geldt die LOF, waarmee je de record grootte zet. Ik kan nog wel wat oude code opvissen denk ik, als de TS er niet uit komt..

  • Priet
  • Registratie: Januari 2001
  • Laatst online: 30-08 20:04

Priet

To boldly do what no one has..

Topicstarter
Uiteindelijke conclusie: Random files gebruiken dus :)

Dat ik daar niet eerder aan gedacht heb |:( Waarom ik in eerste instantie voor Binary heb gekozen weet ik zelf niet eens 8)7

"If you see a light at the end of a wormhole, it's probably a photon torpedo!"


  • Priet
  • Registratie: Januari 2001
  • Laatst online: 30-08 20:04

Priet

To boldly do what no one has..

Topicstarter
Ik heb nu de code als volgt aangepast. De functie waarin dit staat leest uit tekstbetand nr. 1 de .English data uit en uit tekstbestand nr. 2 de .Elven data. Na dit ingelezen te hebben zit Dict helemaal vol. Vervolgens wil ik dit wegschrijven in een Random Acces bestand met de volgende code:
Visual Basic:
1
2
3
4
5
Open strDicFile For Random As #1 Len = Len(Dict(1))
  For lngCounter = 1 To UBound(Dict)
    Put #1, lngCounter, Dict(lngCounter)
  Next lngCounter
Close

Maar, heel vervelend, ik krijg de volgende foutmelding bij het uitvoeren:

Run-time error '59':

Bad record length


Ik zie vast iets over het hoofd, maar wat?

"If you see a light at the end of a wormhole, it's probably a photon torpedo!"


Verwijderd

In ieder geval begint een array op 0 en niet op 1.

  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 11:07

johnwoo

3S-GTE

Je zou eens kunnen spelen met fixed/variable length strings. Voor iedere variable-length string in je type moet je 2 optellen om tot de juiste record length te komen (bij fixed-length strings hoeft dat niet).
CJ_S: Een array begint bij het element dat je als LBound hebt gekozen bij de (re)declaratie :) of anders bij het element dat in de Option Base directive gekozen is. Default is idd wel 0 :)

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


  • Priet
  • Registratie: Januari 2001
  • Laatst online: 30-08 20:04

Priet

To boldly do what no one has..

Topicstarter
Dus ik zou neer moeten zetten:
Visual Basic:
1
Open strDicFile For Random As #1 Len = Len(Dict(1)) + 2

Maar dit werkt niet... :?

'k heb dit vroeger zo vaak gedaan, en nu werkt het gewoon niet meer :(

"If you see a light at the end of a wormhole, it's probably a photon torpedo!"


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 28-08 17:06

Sponge

Serious Game Developer

Okee. Ik post mijn code. De bestanden zijn zo oud dat de datum gewoon op 2060 staat :x, het is echter richting 1998 (damn wat zag die code van me er nog verschrikkelijk uit :o)

anyway:

code:
1
2
3
4
5
Open App.Path + "\POP3.dat" For Random As #1 Len = Len(GEGEVENS(1))
For i = 1 To TOTAALRECORDS
Put #1, , GEGEVENS(i)
Next i
Close #1


udt:

code:
1
2
3
4
5
6
7
8
9
Type RECORD
Namen As String * 30
Types As String * 30
Language As String * 30
Info As String * 400
Website As String * 35
Domain As String * 30
End Type
Global GEGEVENS(200) As RECORD


Edit: bij "put #1, " moet dus recordnummer komen, ik hoop dast het dan goed komt.

  • Priet
  • Registratie: Januari 2001
  • Laatst online: 30-08 20:04

Priet

To boldly do what no one has..

Topicstarter
Nope, ding doet nog steeds niks, zelfde foutmelding :(

"If you see a light at the end of a wormhole, it's probably a photon torpedo!"


  • johnwoo
  • Registratie: Oktober 1999
  • Laatst online: 11:07

johnwoo

3S-GTE

En heb je het al met fixed-length strings geprobeerd?

4200Wp ZO + 840Wp ZW + 1680Wp NW | 14xIQ7+ + 1xDS3-L | MTVenusE | HWP1


Verwijderd

Jhnwoo, welke in dit geval niet gedeclareerd is om op index 1 te beginnen :-) Gelukkig is dit in .Net standaard 0!

  • Priet
  • Registratie: Januari 2001
  • Laatst online: 30-08 20:04

Priet

To boldly do what no one has..

Topicstarter
johnwoo: niet geprobeerd omdat ik dit hier liever niet mee wil werken, dan zit je namelijk weer aan een maximale lengte van je invoer en dat vind ik niet echt ideaal/gebruiksvriendelijk.

CJ_S: C'est que?? Kun je ook meer typen dan 1 á 2 zinnen |:(

Misschien moet ik het gewoon bij het oude laten en telkens als er iets wordt geupdate de hele file in één keer opnieuw wegschrijven.

"If you see a light at the end of a wormhole, it's probably a photon torpedo!"


  • Priet
  • Registratie: Januari 2001
  • Laatst online: 30-08 20:04

Priet

To boldly do what no one has..

Topicstarter
Ik heb het opgelost door de hele file in z'n geheel opnieuw weg te schrijven. Snelheidsverschil is er niet te merken en op deze manier behoud ik het voordeel van ongelimiteerde lengte van de gegevens die worden opgeslagen.

Hoe zit dat eigenlijk met andere talen? Werken die ook volgens hetzelfde principe zodat je daar ook bovenstaand 'trucje' uit moet halen om dit effect te bereiken?

"If you see a light at the end of a wormhole, it's probably a photon torpedo!"

Pagina: 1