Forum: PC-Programmierung Gleichzeitiger Dateizugriff


von Regelmeister (Gast)


Lesenswert?

Hallo,
ich habe ein C-Programm was mir laufen 3 Werte in einer Textdatei 
aktualisiert, alle 10ms, 100ms würde auch noch reichen.
Außerdem habe ich ein C#-Programm, was diese Daten alle 100ms ausliest. 
Leider gibts einen Fehler. Das statische Lesen und Schreiben 
funktioniert, nur nicht das parallele. Hat da jemand eine Lösung dafür? 
Bzw. welche andere Möglichkeit zum Datenaustausch zwischen den beiden 
Programmen besteht?
Lg

von th (Gast)


Lesenswert?


von Regelmeister (Gast)


Lesenswert?

Sieht recht kompliziert aus, gibt es eine einfachere Methode?

von Marcel (Gast)


Lesenswert?


von yalu (Gast)


Lesenswert?

> Leider gibts einen Fehler.

Irgendeinen? ;-)

> Das statische Lesen und Schreiben funktioniert, nur nicht das parallele.

Mit welchen Funktionen? read() und write()?

Wenn dein OS POSIX-konform ist, findest du entsprechende Informationen
im POSIX Programmer's Manual. Zitat aus der write-Dokumention:

  After a write() to a regular file has successfully returned:

   * Any successful read() from each byte position in the file
     that  was modified  by  that  write  shall  return  the  data
     specified by the write() for that position until such byte
     positions are again  modified.

   * Any  subsequent  successful write() to the same byte position
     in the file shall overwrite that file data.

Du kannst davon ausgehen, dass sich in POSIX eine Datei aus der Sicht
von read() und write() wie ein großes, dynamisches Byte-Array verhält.
Wenn ein Byte erfolgreich mit write geschrieben worden ist, kann es auch
mit read wieder gelesen werden, selbst dann, wenn sich die Daten noch in
einem Puffer des OS bzw. des Dateisystems befinden und noch nicht auf
die Festplatte geschrieben worden sind.

Etwas anders verhält es sich, wenn das Anwendungsprogramm eine (zusätz-
liche) eigene Pufferung vornimmt (bspw. in den Funktionen fprintf,
fwrite usw.). Dann funktioniert die Sache zwar immer noch, die Daten
können aber beim OS und damit beim Empfänger verzögert ankommen, je nach
Pufferstrategie.

Im Linux Programmer's Manual steht noch der Hinweis:

  POSIX  requires  that  a  read(2)  which can be proved to occur after
  a write() has returned returns the new data.  Note that not all file
  systems are POSIX conforming.

Wenn du also ein anders OS als Unix/Linux benutzt, brauchst du also nur
in der Dokumentation des OS und des verwendeten Dateisystems nachzu-
schlagen, ob ausreichende POSIX-Konformität besteht, oder ob es ver-
gleichbare Alternativkonstrukte gibt.

Selbst das Windows-API erhebt den Anspruch, in großen Teilen POSIX-
konform zu sein. Es besteht also durchaus die Chance, dass der "Fehler"
nicht durch Windows, sondern von dir selbst verursacht wird.

Anmerkung zum Schluss:

In Unix/Linux macht bspw. der Befehl tail -f von der Möglichkeit des
simultanen Schreibens und Lesens durch zwei unterschiedliche Prozesse
Gebrauch, was auch problemlos funktioniert. Es kann also kein schlechter
Stil sein, so zu verfahren ;-)

von Tom (Gast)


Lesenswert?

yalu, de OP schreibt was von C#. Das schließt *nix zwar lang nicht aus, 
macht es doch aber recht unwahrscheinlich. Spätestens der Unwille Pipes 
(hail to the allmighty pipe!) zu verwenden, bestätigt das.

von yalu (Gast)


Lesenswert?

Tom schrieb:
> yalu, de OP schreibt was von C#. Das schließt *nix zwar lang nicht
> aus, macht es doch aber recht unwahrscheinlich.

Ich habe zwar ebenfalls vermutet, dass es um Windows geht, war mir aber
nicht 100% sicher. Deswegen habe ich mit den OSen angefangen, von denen
ich weiß, daß das Unterfangen realisierbar ist, und zusätzlich einen
Hinweis darauf gegeben, dass es unter Windows evtl. genauso geht.

Ich habe aber gerade keinen Rechner zum Testen hier und keinen Nerv, in
der Loseblattsammlung names MSDN¹ zu wühlen ;-)

¹) MSDN ist doch die offizielle Windows-Dokumentation, oder gibt es
vielleicht noch eine etwas strukturiertere?

von Marcus K. (marcusk)


Lesenswert?

gleichzeitig lesen und schreiben in einer Datei, ist zwar möglich aber 
nicht sehr sinnvoll.
Warum musst du denn das machen? Brauchst du die Daten wirklich in der 
Datei oder hast du dir bloss den weg überlegt um die Daten von C nach C# 
zubekommen?

von Tom (Gast)


Lesenswert?

Regelmeister
> Sieht recht kompliziert aus, gibt es eine einfachere Methode?

Du meine Güte, nimm halt Pipes. Dateien zur Inter-Prozess-Kommunikation 
zu verwenden ist doch tiefstes Mittelalter!

von Regelmeister (Gast)


Lesenswert?

Ja ihr habt mich überzeugt, ich werds mit Pipes versuchen... muss da nur 
schauen wie es jeweils geht in c und c#.

von Arc N. (arc)


Lesenswert?

Die ursprüngliche Methode geht auch zur Not...
Beispiel:
1
// C-Teil, schreiben, Win-API
2
    HANDLE h = CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
3
4
    while (true) {
5
       WriteFile(h, buffer, bufferLen, &written, NULL);
6
    }
7
8
// C#-Teil, lesen
9
var file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
10
var sr = new StreamReader(file, System.Text.Encoding.ASCII);
11
var line = sr.ReadLine();

von Regelmeister (Gast)


Lesenswert?

Soweit bin ich:
1
hPipe = CreateNamedPipe("\\.\pipe\mypipe",PIPE_ACCESS_DUPLEX,FILE_FLAG_OVERLAPPED,2,10,10,0,NULL);
2
  while(ConnectNamedPipe(hPipe,NULL)==0){
3
  }
4
  printf("Pipe-client connected!\n");
Das ist der Code in C, der folgende in C#:
1
 private void button3_Click(object sender, EventArgs e)
2
        {
3
            NamedPipeClientStream anypipe = new NamedPipeClientStream("mypipe");
4
            anypipe.Connect();
5
        }
Leider wird das printf nicht ausgegeben. Der obere Code wird zuerst 
gestartet.

von Klaus W. (mfgkw)


Lesenswert?

Du nimmst den Rückgabewert von ConnectNamedPipe() nur, um in eine
Endlosschleife zu gehen, falls es nicht klappt.

Die Doku sagt dazu:
1
If the operation is synchronous, ConnectNamedPipe does not return
2
until the operation has completed. If the function succeeds, the
3
return value is nonzero. If the function fails, the return value
4
is zero. To get extended error information, call GetLastError.

Hol doch mal den Fehler, vielleicht ist der ja aufschlußreich?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.