Aktuelle Zeit: 04.07.2020 04:11

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 17:32 
Offline
Benutzeravatar

Registriert: 30.10.2010 19:27
Hallo kann mir jemand bei meinem Problem helfen

und zwar möchte ich die grösse eines Listenelementes ermitteln um es dann zu speichern ,aber wie.
Habe schon im Forum ge googelt aber nichts passendes gefunden.

Hier mal mein bisheriger Code :

Code:
Structure fmpro
  form.b
  zeit.d
  meldung.s
EndStructure

Global NewList FMProt.fmpro()

AddElement(FMProt())
FMProt()\form = 1
FMProt()\zeit=1444255255252
FMProt()\meldung="hallaoaoaoaoaoao"

AddElement(FMProt())
FMProt()\form = 2
FMProt()\zeit=144
FMProt()\meldung="hallaoaoa htuuutaoaoaoao"

 If CreateFile(0, "Text.prot")   
   ForEach FMProt()
      *Element.fmpro = @FMProt()
      size = MemorySize(*Element)
   WriteData(MyFileHandle, @FMProt(),size ) ; SizeOf(fmpro))
  Next
EndIf



speziell die Zeile mit ' size = MemorySize(*Element) ' funktioniert nicht so wie ich dachte.
Vielleicht kann mir jemand helfen, ich weiss nicht mehr weiter.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 17:52 
Offline
Benutzeravatar

Registriert: 01.04.2007 20:18
Das wird so nicht wirklich klappen.
Der grosse Problempunkt ist der String in deiner Struktur.
Es ist eigentlich gar nicht der String in FMProt()\meldung,
sondern nur der Pointer, der auf die Speicheradresse zeigt,
wo der String gespeichert ist.

Am besten kann man solche Speicherungen mit JSON erledigen.
Dazu weiteres in der Hilfe nachlesen (F1).

Hier verwende ich einfach mal deinen "Prototyp" um ihn als Datei zu speichern....
egal wieviele Einträge vorhanden sind :

Code:
Structure fmpro
  form.b
  zeit.d
  meldung.s
EndStructure

Global NewList FMProt.fmpro()

AddElement(FMProt())
FMProt()\form = 1
FMProt()\zeit=1444255255252
FMProt()\meldung="hallaoaoaoaoaoao"

AddElement(FMProt())
FMProt()\form = 2
FMProt()\zeit=144
FMProt()\meldung="hallaoaoa htuuutaoaoaoao"

; Json erstellen

jSon = CreateJSON(#PB_Any, #PB_JSON_NoCase)

If jSon
  ; Liste einfügen
  InsertJSONList(JSONValue(jSon), FMProt())
  ; Json speichern
  If Not SaveJSON(jSon, "Text.json", #PB_JSON_PrettyPrint)
    Debug "Fehler beim Speichern"
  EndIf
  ; Json freigeben
  FreeJSON(jSon) 
EndIf


Jetzt kannst du dir die datei mit einem Texteditor ansehen...

_________________
PureBasic 5.72 LTS (Windows x86/x64) | Windows10 Pro x64 | Z370 Extreme4 | i7 8770k | 32GB RAM | iChill GeForce RTX 2080 Super | HAF XF Evo​​


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 17:53 
Offline
Ein Admin
Benutzeravatar

Registriert: 29.08.2004 20:20
Wohnort: Saarbrücken
Hey McKay!

So einfach funktioniert das leider nicht, wenn Strings im Spiel sind.
Normalerweise würde man SizeOf(fmpro) nutzen um die Strukturgröße zu ermitteln, denn Strukturen sind erst mal immer statisch und gleich groß. Strings in Strukturen sind nichts anderes als Pointer zum eigentlichen String. Das heißt egal wie lange der String ist, den du in deinem strukturierten Element speicherst, das Element selbst bleibt gleich groß. Allerdings zeigt das String-Feld (in deinem Fall 'meldung.s') zum eigentlich String im Speicher.

Der Einfachheit halbe würde ich jedes Strukturelement einzeln schreiben:
Code:
Structure fmpro
   form.b
   zeit.d
   meldung.s
EndStructure

Global NewList FMProt.fmpro()

AddElement(FMProt())
FMProt()\form = 1
FMProt()\zeit=1444255255252
FMProt()\meldung="hallaoaoaoaoaoao"

AddElement(FMProt())
FMProt()\form = 2
FMProt()\zeit=144
FMProt()\meldung="hallaoaoa htuuutaoaoaoao"

If CreateFile(0, "Text.prot")
   ForEach FMProt()
      *Element.fmpro = @FMProt()
      WriteByte(MyFileHandle, *Element\form)
      WriteDouble(MyFileHandle, *Element\zeit)
      ; Jetzt meldung
      WriteString(MyFileHandle, *Element\meldung)
      ; und Nullterminierung
      WriteByte(MyFileHandle, 0)
   Next
EndIf

_________________
Ubuntu Gnome 20.04 LTS x64, PureBasic 5.72 x64 (außerdem 4.41, 4.50, 4.61, 5.00, 5.10, 5.11, 5.21, 5.22, 5.30, 5.31, 5.40, 5.50, 5.60, 5.71b2)
"Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 18:04 
Offline
Benutzeravatar

Registriert: 04.08.2009 17:24
NicTheQuick hat geschrieben:
Code:
   ForEach FMProt()
      *Element.fmpro = @FMProt()
      WriteByte(MyFileHandle, *Element\form)
      WriteDouble(MyFileHandle, *Element\zeit)
      ; Jetzt meldung
      WriteString(MyFileHandle, *Element\meldung)
      ; und Nullterminierung
      WriteCharacter(MyFileHandle, 0) <-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
   Next
Unbedingt ein WriteCharacter anstatt WriteByte verwenden. Zusätzlich würde ich als erstes Element in der Datei die Anzahl der Listeinträge in einem Long speichern. Beim Auslesen liest du dann als erster die Anzahl der Listeinträge und durchläufst dann eine For-Schleife.


Bisonte hat geschrieben:
Am besten kann man solche Speicherungen mit JSON erledigen.
Auf JSON würde ich an deiner Stelle verzichten. Das ist in jeder Beziehung der absolute Killer.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 18:39 
Offline
Ein Admin
Benutzeravatar

Registriert: 29.08.2004 20:20
Wohnort: Saarbrücken
Josh hat geschrieben:
Unbedingt ein WriteCharacter anstatt WriteByte verwenden. Zusätzlich würde ich als erstes Element in der Datei die Anzahl der Listeinträge in einem Long speichern. Beim Auslesen liest du dann als erster die Anzahl der Listeinträge und durchläufst dann eine For-Schleife.

Sicher? Da WriteString() standardmäßig als UTF-8 schreibt, sollte ein Nullbyte reichen. Zwei wären eines zu viel.

_________________
Ubuntu Gnome 20.04 LTS x64, PureBasic 5.72 x64 (außerdem 4.41, 4.50, 4.61, 5.00, 5.10, 5.11, 5.21, 5.22, 5.30, 5.31, 5.40, 5.50, 5.60, 5.71b2)
"Die deutsche Rechtschreibung ist Freeware, du darfst sie kostenlos nutzen – Aber sie ist nicht Open Source, d. h. du darfst sie nicht verändern oder in veränderter Form veröffentlichen."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 19:03 
Offline
Benutzeravatar

Registriert: 04.08.2009 17:24
NicTheQuick hat geschrieben:
Sicher? Da WriteString() standardmäßig als UTF-8 schreibt, sollte ein Nullbyte reichen. Zwei wären eines zu viel.

Nein, nicht sicher. Eher sicher, dass ich da falsch gelegen bin :oops:
Jetzt muss ich bei mir im Code mal gucken, wie ich das gemacht habe.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 19:28 
Offline
Benutzeravatar

Registriert: 24.11.2004 13:12
Wohnort: Germany
Ich will auch :mrgreen:

I like XML

Code:

Structure fmpro
  form.b
  zeit.d
  meldung.s
EndStructure

Procedure LoadProtocolData(Path.s, List Protocol.fmpro())
  Protected filename.s, xml
 
  filename = Path + "ProtocolData.xml"
  If FileSize(filename) > 0
    xml = LoadXML(#PB_Any, filename)
    If xml And XMLStatus(xml) = #PB_XML_Success
      ExtractXMLList(MainXMLNode(xml), Protocol(), #PB_XML_NoCase)
      FreeXML(xml)
    EndIf
  EndIf
 
EndProcedure

; ----

Procedure SaveProtocolData(Path.s, List Protocol.fmpro())
  Protected filename.s, xml
 
  filename = Path + "ProtocolData.xml"
  xml = CreateXML(#PB_Any)
  If xml
    If InsertXMLList(RootXMLNode(xml), Protocol())
      FormatXML(xml, #PB_XML_ReFormat)
      SaveXML(xml, filename)
    EndIf
  EndIf

EndProcedure

; ----


Global NewList FMProt.fmpro()

AddElement(FMProt())
FMProt()\form = 1
FMProt()\zeit=1444255255252
FMProt()\meldung="hallaoaoaoaoaoao"

AddElement(FMProt())
FMProt()\form = 2
FMProt()\zeit=144
FMProt()\meldung="hallaoaoa htuuutaoaoaoao"

path.s = GetUserDirectory(#PB_Directory_Documents)

SaveProtocolData(path, FMProt())


CallDebugger

LoadProtocolData(path, FMProt())

CallDebugger

_________________
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul / OPC-Helper DLL
PB v3.30 / v5.4x - OS Mac Mini OSX 10.xx / Window 10 Pro. (X64) /Window 7 Pro. (X64) / Window XP Pro. (X86) / Ubuntu 14.04
Downloads auf My Webspace


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 20:16 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Ich würde es wie Bisonte machen!
Keine Ahnung was die Bemerkung von Josh bedeuten soll.

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 20:24 
Offline
Benutzeravatar

Registriert: 04.08.2009 17:24
Josh hat geschrieben:
Jetzt muss ich bei mir im Code mal gucken, wie ich das gemacht habe.
Ja, hab bei mir auch WriteByte verwendet. Na hab zumindest hab ich für ein wenig Verwirrung in einem langweiligen Thread gesorgt :mrgreen:


mk-soft hat geschrieben:
Ich will auch :mrgreen:
I like XML
Ich hab zwar mit XML noch nicht herumexperimentiert, aber kann mir gut vorstellen, dass das genau so ein Performancekiller wie JSON ist.


HeX0R hat geschrieben:
Keine Ahnung was die Bemerkung von Josh bedeuten soll.
JSON ist ja vielleicht gut geeignet, Daten zwischen zwei Programmen auszutauschen. Kann auch gut dazu geeignet sein, wenn dein Anwender zwischendurch gerne mal eine Zigarette raucht oder einen Kaffee trinkt. Ich hatte mal herumexperimentiert und bin auf einen zeitlichen Faktor von 70 bis 100 gegenüber dem System von NicTheQuick gekommen. Die aufgeblähten Dateien spielen zwar heute kaum mehr eine Rolle, sind aber trotzdem unnötig.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: Grösse eines Listenelementes ermitteln
BeitragVerfasst: 17.09.2019 20:58 
Offline
Benutzeravatar

Registriert: 10.09.2004 09:59
Es war hier nicht nach einer besonders performanten Lösung gefragt.
Und wenn es ums Laden und Speichern von Maps oder Listen geht, gibt's nix einfacheres, die XML Lösung ist natürlich vergleichbar, aber XML erzeugt m. E. zuviel Overhead.
Du brauchst dich um nix zu kümmern, musst deinen Code auch nicht anpassen, wenn Du die Struktur der Liste/Map änderst.

Klar, wenn es sauschnell sein muss, würde ich das auch nicht nutzen, aber das steht hier nirgends.

[Edit]
Als "Killer" würde ich es auch nicht bezeichnen.
Ich habe ein Projekt mit einer Map bestehend aus ca. 3000 Modbus Registern, inkl. jeweils Register, Typ, Name, Beschreibung, noch nen paar Flags. Habe noch nie die Zeit beim Laden und Speichern gestoppt, aber gefühlt bin ich bei etwa einer Sekunde.

_________________
Link tot?
Ändere h3x0r.ath.cx in hex0rs.coderbu.de und alles wird gut.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 12 Beiträge ]  Gehe zu Seite 1, 2  Nächste

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 5 Gäste


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  
cron

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye