Hallo liebe Leut,
ich möchte mit einem kleinen C Programm kontinuierlich in eine Datei
schreien (nur schreiben, da ein anderes Programm kontinuierlich lesen
soll).
vom Prinzip soll das so aufgebaut werden
1
FILE * pFile;
2
pFile = fopen ("tmp.ad","w+");
3
if (pFile!=NULL){
4
while(1){
5
6
char * data = "test"
7
8
fwrite( data, sizeof(data), 1, pFile );
9
10
usleep(1000000) //sleep 1 second
11
}
12
}
13
fclose ( pFile );
aber 1. stimmt da was nicht, weshalb er die datei zwar erzeugt aber
nichts reinschreibt...
2. soweit ich weiß, würde er dann einfach drauf losschreiben und mir die
datei nach und nach befüllen... soll aber eigentlich nur den Inhalt
"ersetzen".
als letztes Problem habe ich noch (neues kurzes thema):
mit dem befehl read_val(params) bekomme ich ein 'double' zurück...
wie kann ich das "verwurschteln" das ich dies dann als char
weiterverarbeiten kann und dann in die datei schreiben kann?
ziel ist es das es etwa so aussieht:
1
char * data = "anfang" & read_val(params) & "ende";
vielen dank für die Hilfe
& evtl. kann mir mal jemand sagen wie ich C-Code hier richtig
deklariere...
Problem N konnte ich so lösen:
snprintf(buffer, sizeof(buffer), "(%g, %g)", read_val(parm),
read_val(parm));
jetzt stellt sich nur noch die Frage wie ich "buffer" in die Daten
kontinuierlich schreiben kann ohne die Datei jedes mal neu zu öffnen!
Rufus Τ. F. schrieb:> baer schrieb:>> char * data = "test">>>> fwrite( data, sizeof(data), 1, pFile );>> Was gibt hier der sizeof-Operator zurück?
vermutlich "kacke" :D ...
hab das auch nur kopiert. Ist das Falsch???
was muss hier hin?
baer schrieb:> Ist das Falsch???> was muss hier hin?
Was willst Du hier bestimmen? Die Größe des Pointers "data" oder die
Länge des Strings, auf den der Pointer zeigt?
Wenn Du fwrite verwendest, kannst Du auch fprintf nutzen ...
Außer, was Rufus schon sagte:
Wenn Du Dateien mit fopen statt mit open öffnest, benutzt stdio einen
Buffer. Den kannst du mit fflush(pFile) committen. Möglicherweise sieht
es deshalb so aus, als wäre die Datei leer, obwohl du sie beschreibst.
Du solltest außerdem wirklich den Returncode von snprintf testen! Wenn
der Buffer nicht groß genug ist, kann das zu "Müll" im Output führen...
Rene H. schrieb:> Vor dem snprintf Buffer Initialisieren mit memset(buffer, 0,> sizeof(buffer))
Nö, dann werden nullbytes geschrieben. besser size_t s = snprintf( und
spater s stat sizeof(data)
Oder gleich fprintf verwenden, oder strlen.
PS: Wäre ein FIFO statt ein File hier nicht besser?
Daniel A. schrieb:> Rene H. schrieb:>> Vor dem snprintf Buffer Initialisieren mit memset(buffer, 0,>> sizeof(buffer))>> Nö, dann werden nullbytes geschrieben. besser size_t s = snprintf( und> spater s stat sizeof(data)
Nö, das funktioniert nur solange der String gleich gross oder grösser
wird.
Grüsse,
René
Daniel A. schrieb:> PS: Wäre ein FIFO statt ein File hier nicht besser?
ha... genau das Problem mit dem wenn der "String" die länge ändert habe
ich jetzt...
FIFO klingt (nach kurzen Googeln) super, und genau nachdem was ich
suche...
> evtl n kurzes how to?
Danke
baer schrieb:> ich möchte mit einem kleinen C Programm kontinuierlich in eine Datei> schreien (nur schreiben, da ein anderes Programm kontinuierlich lesen> soll).
Bekommst Du die beiden Jobs Schreiben und Lesen synchronisiert? Wenn
nicht, kassierst Du sporadische Zugriffsfehler, weil vom Schreibprozess
gerade geöffnet.
Daniel A. schrieb:> PS: Wäre ein FIFO statt ein File hier nicht besser?
Auch nein, FIFO löst das grössen Problem in einem File nicht. Das
Problem ist das File, nicht wie es da reinkommt.
Grüsse,
René
Ein FIFO ist kein gewöhnliches file, sondern ein spezielles first in
first out file. Ein Programm kann nicht reinschreiben solange keins
davon liest, und ein Programm kann nicht davon Lesen solange keins
schreibt. Ein Fifo file verbraucht auf der HDD keinen Speicherplatz.
Ein normales file wäre auf jeden fall Murks. Eigentlich gibt es fast nie
einen grund kontinuierlich Daten zu schreiben, die eventuell nicht
gelesen werden. Sollten wirklich sich kontinuierlich verändernde Werte
in mehreren Programmen verfügbar sein, währe eventuell shared memory in
Kombination mit c11 atomics + volatile eine gute methode. Andernfalls
würde ich raten eine Library zu schreiben um die Werte abzufragen, wenn
diese tatsächlich benötigt werden, z.B. mit hillfe von sockets, oder
durch verwenden einer bestehenden Message queue library. Oder man nutzt
dbus.
Zusammengefasst, löse es irgendwie, aber besser nicht so wie jetzt.
PS: Sobald man rewind oder fseek im Programm hat, macht man meist was
falsch oder zumindest nicht ideal.
Daniel A. schrieb:> löse es irgendwie, aber besser nicht so wie jetzt.
Mach öfter eine neue Datei auf und schmeiß die alten nach dem lesen weg?
Zu lange/große Datei macht selten glücklich (Zeitproblem bei einigen
GB).
Daniel A. schrieb:> Ein FIFO ist kein gewöhnliches file, sondern ein spezielles first in> first out file. Ein Programm kann nicht reinschreiben solange keins> davon liest, und ein Programm kann nicht davon Lesen solange keins> schreibt. Ein Fifo file verbraucht auf der HDD keinen Speicherplatz.>> Ein normales file wäre auf jeden fall Murks. Eigentlich gibt es fast nie> einen grund kontinuierlich Daten zu schreiben, die eventuell nicht> gelesen werden. Sollten wirklich sich kontinuierlich verändernde Werte> in mehreren Programmen verfügbar sein, währe eventuell shared memory in> Kombination mit c11 atomics + volatile eine gute methode. Andernfalls> würde ich raten eine Library zu schreiben um die Werte abzufragen, wenn> diese tatsächlich benötigt werden, z.B. mit hillfe von sockets, oder> durch verwenden einer bestehenden Message queue library. Oder man nutzt> dbus.>> Zusammengefasst, löse es irgendwie, aber besser nicht so wie jetzt.>> PS: Sobald man rewind oder fseek im Programm hat, macht man meist was> falsch oder zumindest nicht ideal.
Natürlich. Aber das löst das Problem nicht.
Grüsse,
René
Dann verstehe ich das Problem nicht. Gibt es einen Grund, warum du in
wiederholt in ein File schreiben musst, oder brauchst du ein
Minimalbeispiel zu einer der vorgeschlagenen Möglichkeiten, oder was ist
es? Was ist das Ziel der ganzen Übung?
Daniel A. schrieb:> Dann verstehe ich das Problem nicht. Gibt es einen Grund,
Ich vermute er will lediglich aktuelle Messdaten sicherstellen.
Aber so ganz klar ist mir die Intention auch nicht.
Grüsse,
René
Rene H. schrieb:> Daniel A. schrieb:>> PS: Wäre ein FIFO statt ein File hier nicht besser?>> Auch nein, FIFO löst das grössen Problem in einem File nicht.
Was ist "das grössen Problem in einem File"?
Das ergibt ja schon orthografisch gar keinen Sinn. und auch sonst nicht
so wirklich. Um zwei Prozesse miteinander kommunizieren zu lassen, sind
Files fast nie die Lösung. FIFOs schon eher. Aber ohne Details des
Problems zu kennen, können wir über die Lösung nur raten.
man 5 ipc
Axel S. schrieb:> Rene H. schrieb:>> Daniel A. schrieb:>>> PS: Wäre ein FIFO statt ein File hier nicht besser?>>>> Auch nein, FIFO löst das grössen Problem in einem File nicht.>> Was ist "das grössen Problem in einem File"?>> Das ergibt ja schon orthografisch gar keinen Sinn. und auch sonst nicht> so wirklich. Um zwei Prozesse miteinander kommunizieren zu lassen, sind> Files fast nie die Lösung. FIFOs schon eher. Aber ohne Details des> Problems zu kennen, können wir über die Lösung nur raten.>> man 5 ipc
Mein Fehler, ich hatte in der Tat das mit dem zweiten Prozess übersehen.
Dann ist FIFO sicher eine Alternative.
Grüsse,
René
nun ja,
ich habe wie schon erraten messdaten (aktuell. 5 adcs die stromwerte von
z.b. kühlschrank, waschmaschine, licht... abrufen)
diese rufen gleichzeitig etwa 10 prozesse live (halt eben mit
minimalster verzögerung) ab (also diverse "monitore")...
da ich aber die i2c schnittstelle nicht überlasten will, cache ich die
daten und lese nur den cache!
die obigen lösungen funktionieren aber nicht ganz ohne haken... groß
wird die datei nicht, da ich alle daten wieder überschreibe!
=> sichern in eine db folgt noch, aber da brauch ich weit aus weniger
daten (5 minutentakt) und das macht mein .c in ferner Zukunft selbst...
fifo klingt echt spannend... aber ich habe keinen echten "ansatz"...
besonders hakt es hier sicherlich wie ich die daten dann zurück in php
bekomme... aber auch hier wäre vermutlich n kleines .c kein problem das
ich über exec aufrufe!
nun wo lade ich meine daten ab => speicher statt datei
und wie komme ich da wieder ran...
ein kleines how to wäre echt nett...
danke für die konstruktiven gedanken die ihr mit mir teilt!
Bei einem FIFO können geschriebene Daten aber nur einmal gelesen werden,
selbst wenn mehrere Prozesse darauf lesend zugreifen bekommt nur einer
die Daten. Für diesen Anwendungsfall währe es damit wohl ungeeignet.
Axel S. schrieb:> Um zwei Prozesse miteinander kommunizieren zu lassen, sind> Files fast nie die Lösung.
Das seh ich anders. Files sind GENAU die Lösung. Und zwar 'memory
mapped'.
Schau mal bei Google nach 'memory mapped files'. Da wird Dir geholfen.
baer schrieb:> sichern in eine db folgt noch, aber da brauch ich weit aus weniger daten> (5 minutentakt) und das macht mein .c in ferner Zukunft selbst...
Du kannst auch Deine aktuellen Daten in einer Datenbank speichern. Im
Arbeitsspeicher; sieh Dir mal SQLite an. Das kann das, und das macht das
mit vorzüglicher Performance, und ist in reinem C geschrieben.
Und für die Langzeitarchivierung kannst Du das auch nehmen, SQLite kann
selbstverständlich auch mit Dateien arbeiten.
Vielleicht bin ich ein Hipster, aber ich würd' dbus nehmen. Die eine
Anwendung emittiert ein Signal, die anderen hören darauf und gut ist.
Die meisten anderen Lösungen sind "ich bau mir mein eigenes IPC nur
schlechter als dbus".
baer schrieb:> Problem N konnte ich so lösen:> snprintf(buffer, sizeof(buffer), "(%g, %g)", read_val(parm),> read_val(parm));
Falls das funktioniert, dann nur zufällig! Ich nehme mal an, dass
read_val() von irgenwoher seriell einliest. Es gibt aber keine Garantie,
dass das erste read_val(parm) in dieser Zeile vor dem zweiten
read_val(parm) aufgerufen wird. Das kann mal so, mal andersrum
geschehen.
Die richtige Lösung lautet daher:
Also, so wie sich das ganze jetzt anhört, fällt die Anwendung in das
Publish/Subscribe-Pattern:
https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern.
Eine Quelle (Publisher) von Daten, mehrere Subscriber, die diese Daten
erhalten wollen. Für diese Anwendung gibt es bereits fertige, erprobte
Lösungen, DBus und Redis z.B.
Warum nicht was fertiges nehmen?