www.mikrocontroller.net

Forum: PC-Programmierung Gleichzeitiger Dateizugriff


Autor: Regelmeister (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: th (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Regelmeister (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht recht kompliziert aus, gibt es eine einfachere Methode?

Autor: Marcel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;-)

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Marcus Kunze (marcusk)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Regelmeister (Gast)
Datum:

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

Autor: Arc Net (arc)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die ursprüngliche Methode geht auch zur Not...
Beispiel:
// C-Teil, schreiben, Win-API
    HANDLE h = CreateFile(fileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);

    while (true) {
       WriteFile(h, buffer, bufferLen, &written, NULL);
    }

// C#-Teil, lesen
var file = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
var sr = new StreamReader(file, System.Text.Encoding.ASCII);
var line = sr.ReadLine();

Autor: Regelmeister (Gast)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

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

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

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.