WriteFile - ReadFile
Re: WriteFile - ReadFile
Es gibt unter PureBasic nur ReadFile () für's Lesen, OpenFile () für's Lesen und für's Schreiben und CreateFile (), was wie OpenFile () ist, nur, dass die existierende Datei überschrieben wird.
Für Dein Problem, schätze ich, benötigen wir weitere Codebeispiele!
Eine reine Übersetzung für den Binary-Mode gibt es, soweit ich weiß, nicht.
Für Dein Problem, schätze ich, benötigen wir weitere Codebeispiele!
Eine reine Übersetzung für den Binary-Mode gibt es, soweit ich weiß, nicht.
- NicTheQuick
- Ein Admin
- Beiträge: 8807
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: WriteFile - ReadFile
Man muss eine Datei nicht als binary öffnen. Dateien sind immer binary. Wenn du allerdings Rohdaten schreiben willst, die direkt an einer Speicheradresse stehen, dann kannst du 'WriteData()' nehmen.
Wenn du 'WriteString()' nutzt, wird kein #CRLF$ am Ende geschrieben. Das heißt, wenn du das dann immer noch in der Datei hast, dann ist das wohl schon in deinem String drin.
Wenn du 'WriteString()' nutzt, wird kein #CRLF$ am Ende geschrieben. Das heißt, wenn du das dann immer noch in der Datei hast, dann ist das wohl schon in deinem String drin.
Re: WriteFile - ReadFile
Hat er ja indirekt gesagt, dass er Zeilenumbrüche im String hat.
Den Code bitte im ASCII-Modus ausführen.
@Kiffi: Whooops.
Bearbeitet.
Code: Alles auswählen
Define file$
Define ff
Define String$
String$ = "Hallo," + #CRLF$ + "Welt!"
file$ = SaveFileRequester ("", "", "", #Null)
ff = OpenFile (#PB_Any, file$)
If ff
WriteData (ff, @ String$, Len (String$))
CloseFile (ff)
EndIf
@Kiffi: Whooops.

Zuletzt geändert von es_91 am 14.12.2014 21:13, insgesamt 1-mal geändert.
-
- Beiträge: 700
- Registriert: 19.10.2014 15:51
- Kontaktdaten:
Re: WriteFile - ReadFile
So, nun bin ich auf der richtigen Spur:
Die Datei, die der Server sendet, ist ca. 2 MB gross.
Das scheint zu gross zu sein.
Kleinere Dateien liest der PB-Clienten fehlerlos.
Bis 94341 Byte Stringlänge empfängt der Client richtig, danach gibt es Fehler.
Am Server kann es kaum liegen, da GFA-Basic Clients problemlos Strings beliebiger Größe empfangen können.
Ich rufe mit folgendem Code Daten per Timer alle 1/100 Sec. vom Server ab:
StringFromServer ist ein Globaler String
In einer anderen Procedure wird dieser String auf Nachrichten untersucht.
Die Datei, die der Server sendet, ist ca. 2 MB gross.
Das scheint zu gross zu sein.
Kleinere Dateien liest der PB-Clienten fehlerlos.
Bis 94341 Byte Stringlänge empfängt der Client richtig, danach gibt es Fehler.
Am Server kann es kaum liegen, da GFA-Basic Clients problemlos Strings beliebiger Größe empfangen können.
Ich rufe mit folgendem Code Daten per Timer alle 1/100 Sec. vom Server ab:
Code: Alles auswählen
Procedure ReadNetData()
Protected Puffergroesse.l, Laenge.l, Temp.s
Define *MemoryID
Puffergroesse = 8192
*MemoryID = AllocateMemory(Puffergroesse)
If *MemoryID
Repeat
Laenge = ReceiveNetworkData(ConnectionID, *MemoryID, Puffergroesse)
Temp + PeekS(*MemoryID, Puffergroesse,#PB_Ascii) ;es muss zwingend #PB_ASCII sein, weil die Daten vom Server im ASCII Format gesendet werden.
;sonst bleibt es bei Umlauten hängen.
Until Laenge < Puffergroesse
FreeMemory(*MemoryID)
EndIf
StringFromServer=StringFromServer+temp
EndProcedure
In einer anderen Procedure wird dieser String auf Nachrichten untersucht.
Ich programmiere nur noch mit Linux.
Linux Mint 21.x
Linux Mint 21.x
Re: WriteFile - ReadFile
Hallo stevie1401,
Deine Netzwerkschleife:
Damit wird das nicht gehen!
Ich sehe folgende Probleme:
Kannst Du sicherstellen, dass der Server nur Strings schickt, die keine "NULL-Zeichen" enthalten?
Es gibt nämlich auch Programmiersprachen, da dürfen Strings auch NULL-Zeichen als gültige Zeichen enthalten! Wenn das bei Deinem Server der Fall ist, musst Du das Empfangen anders regeln.
In PureBasic kennzeichnet ein NULL-Zeichen immer das String-Ende!
Eine endgültige Antwort ist also erst möglich, wenn genaue Informationen über das Format der gesendeten Datenpakete des Servers vorliegen.
cu,
guido
Deine Netzwerkschleife:
Code: Alles auswählen
Repeat
Laenge = ReceiveNetworkData(ConnectionID, *MemoryID, Puffergroesse)
Temp + PeekS(*MemoryID, Puffergroesse,#PB_Ascii) ;es muss zwingend #PB_ASCII sein, weil die Daten vom Server im ASCII Format gesendet werden.
;sonst bleibt es bei Umlauten hängen.
Until Laenge < Puffergroesse
Ich sehe folgende Probleme:
- Der Client weiß nicht, wie groß der zu empfangende String-Paket sein wird! ... oder gibt es eine bestimmte Zeichenfolge (z.B. "@@ENDE-DES-STRINGS@@"), die das String-Ende kennzeichnet?
- Wenn Du weniger 8192 Bytres empfängst bedeutet, das noch nicht, dass wirklich alle Daten des String-Pakets angekommen sind.
- Mit "PeekS(*MemoryID, Puffergroesse,#PB_Ascii)" liest Du zu viele Daten ein, wenn Laenge < Puffergroesse ist:
==> Du solltest "PeekS(*MemoryID, Laenge,#PB_Ascii)" verwenden!
Kannst Du sicherstellen, dass der Server nur Strings schickt, die keine "NULL-Zeichen" enthalten?
Es gibt nämlich auch Programmiersprachen, da dürfen Strings auch NULL-Zeichen als gültige Zeichen enthalten! Wenn das bei Deinem Server der Fall ist, musst Du das Empfangen anders regeln.
In PureBasic kennzeichnet ein NULL-Zeichen immer das String-Ende!
Eine endgültige Antwort ist also erst möglich, wenn genaue Informationen über das Format der gesendeten Datenpakete des Servers vorliegen.
cu,
guido
Windows 10
PB Last Final / (Sometimes testing Beta versions)
PB Last Final / (Sometimes testing Beta versions)
-
- Beiträge: 700
- Registriert: 19.10.2014 15:51
- Kontaktdaten:
Re: WriteFile - ReadFile
Nun, eigentl. mache ich das mit dem PB-Client genauso wie ich es mit dem GFA-Basic Client mache.
Alles was reinkommt wird in den String "StringFromServer" gelegt.
In einer anderen Procedure wird nun dieser String abgefragt, ob bestimmte Inhalte in diesem String sind:
So sucht er z.B. den String nach <<karten>><</karten>> ab, um die Spielkarten des Spieler zu bekommen.
Alles was zwischen <<karten>><</karten>> ist, sind Spielkarten.
So gibt es viele Suchbegriffe, nach denen gesucht wird. Habe ich <<suchbegriff>> gefunden, muss ich nach <</suchbegriff>> suchen. Habe ich <</suchbegriff>> gefunden, habe ich die gewünschten Daten, indem ich <<suchbegriff>>String<</suchbegriff>> mir schnappe und verarbeite.
Ich habe also immer Stringanfang und Stringende.
Unter GFA-Basic funktioniert das mit Stringlängen beliebiger Größe. Es kann also ein ellenlanger String zwischen <<suchbegriff>> und <</suchbegriff>> sein.
In meinem PB Programm kommen Fehler, wenn der String zwischen <<suchbegriff>> und <</suchgebriff>> länger als 94341 Byte ist.
"NULL-Zeichen" schliesse ich aus, da ich den Server selbst programmiert habe und meine GFA-Client auch nicht damit umgehen können.
Der Fehler liegt eindeutig im PB-Client.
Alles was reinkommt wird in den String "StringFromServer" gelegt.
In einer anderen Procedure wird nun dieser String abgefragt, ob bestimmte Inhalte in diesem String sind:
So sucht er z.B. den String nach <<karten>><</karten>> ab, um die Spielkarten des Spieler zu bekommen.
Alles was zwischen <<karten>><</karten>> ist, sind Spielkarten.
So gibt es viele Suchbegriffe, nach denen gesucht wird. Habe ich <<suchbegriff>> gefunden, muss ich nach <</suchbegriff>> suchen. Habe ich <</suchbegriff>> gefunden, habe ich die gewünschten Daten, indem ich <<suchbegriff>>String<</suchbegriff>> mir schnappe und verarbeite.
Ich habe also immer Stringanfang und Stringende.
Unter GFA-Basic funktioniert das mit Stringlängen beliebiger Größe. Es kann also ein ellenlanger String zwischen <<suchbegriff>> und <</suchbegriff>> sein.
In meinem PB Programm kommen Fehler, wenn der String zwischen <<suchbegriff>> und <</suchgebriff>> länger als 94341 Byte ist.
"NULL-Zeichen" schliesse ich aus, da ich den Server selbst programmiert habe und meine GFA-Client auch nicht damit umgehen können.
Der Fehler liegt eindeutig im PB-Client.
Ich programmiere nur noch mit Linux.
Linux Mint 21.x
Linux Mint 21.x
- CodeCommander
- Beiträge: 213
- Registriert: 02.03.2014 16:06
~ DELETE ~
Zuletzt geändert von CodeCommander am 18.01.2015 14:55, insgesamt 1-mal geändert.
~ DELETE ~
Re: WriteFile - ReadFile
Wir hatten neulich das Experiment, wieviele Zeichen ein PB-String verarbeiten kann, es sind wohl so um eine Milliarde Zeichen im ASCII-Modus.
- NicTheQuick
- Ein Admin
- Beiträge: 8807
- Registriert: 29.08.2004 20:20
- Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti - Wohnort: Saarbrücken
Re: WriteFile - ReadFile
Hier mal eine korrigierte Fassung deines Codes. Ich hoffe ich habe jetzt selbst nichts übersehen.
Code: Alles auswählen
EnableExplicit
#PUFFER_GROESE = 8192
#TIMEOUT = 1000 ;Das hier auf 0 setzen, wenn kein Timeout benutzt werden soll.
Procedure ReadNetData()
Protected Laenge.i, Temp.s
Protected timeout.i
Protected *MemoryID
*MemoryID = AllocateMemory(#PUFFER_GROESE)
If *MemoryID
Repeat
; Starte das Timeout.
timeout = ElapsedMilliseconds() + #TIMEOUT
Laenge = ReceiveNetworkData(ConnectionID, *MemoryID, #PUFFER_GROESE)
; Erst wenn auch nach dem Timeout keine Daten mehr kommen, brechen wir das Empfangen ab.
; Allerdings bedeutet das noch nicht unbedingt, dass nicht noch etwas kommen könnte.
; Normalerweise sollte der Server zuerst die Größe der Daten schicken und dann sollte
; der Client so lange auf Daten warten, bis alles empfangen wurde.
If (Laenge = 0 And ElapsedMilliseconds() >= timeout)
Break
EndIf
; Lies nur so viele Zeichen mit PeekS aus dem Speicher wie auch empfangen wurden.
Temp + PeekS(*MemoryID, Laenge, #PB_Ascii)
ForEver
FreeMemory(*MemoryID)
EndIf
StringFromServer + Temp
EndProcedure