AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Simultaner Zugriff auf Datei

Ein Thema von kkoe · begonnen am 30. Mai 2014 · letzter Beitrag vom 3. Jun 2014
Antwort Antwort
Seite 1 von 2  1 2   
kkoe

Registriert seit: 6. Mai 2014
3 Beiträge
 
#1

Simultaner Zugriff auf Datei

  Alt 30. Mai 2014, 17:26
Hallo zusammen,

ich programmiere erst seit kurzem mit Delphi und habe ein Problem, was ich bisher nicht im Netz, in Foren oder sonstigem beschrieben gefunden habe. (Und dennoch scheint es mir ein häufig vorkommendes Problem zu sein )

Das Problem: ich habe zwei Programme, die beide auf eine Datei zugreifen sollen (das eine schreibt Daten hinein, das andere liest diese). Das ganze geschieht zyklisch, aber nicht in festen Zeitabständen, sodass das Lese-Programm (welches ich nur beeinflussen kann) alle X-Millisekunden den Zeitstempel der Datei auf eine Aktualisierung überprüft und dann mit dem Auslesen beginnen würde. Bei der Abfrage des Zeitstempels kann/kommt es z.T. zu gleichzeitigem Zugriff beider Programme auf die Datei, was zum Programmabsturz führt.

Ich hatte versucht, das Lesen des Zeitstempels über try...except abzufangen, funktioniert aber nicht. Gibt es in Delphi andere Möglichkeiten, dieses Problem zu umgehen, ohne beide Programme von außen schedulen zu müssen??
Mir würde es zudem genügen, wenn sich das Lese-Programm "devot" verhält, d.h. seinen Zugriff auf die Datei nicht einfordert, sondern einfach wartet, bis das Schreibe-Programm fertig ist.


Vielen Dank schon einmal!
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Simultaner Zugriff auf Datei

  Alt 30. Mai 2014, 18:04
Rewrite öffnet die Datei exclusiv. Währenddessen in eine zweites Rewrite nicht möglich. (Nur) das muß man abfangen, dem Reset ist es egal.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.145 Beiträge
 
Delphi 12 Athens
 
#3

AW: Simultaner Zugriff auf Datei

  Alt 30. Mai 2014, 20:22
Grundsätzlich können alle Rechte gewehrt/gesperrt werden.

Beim Zugriff auf eine Datei muß man angeben was man für Recht haben muß (Lesen und/oder Schreiben) und dabei kann man auch angeben welche weiteren Zugriffe gleichzeitig erlaubt sind, egal ob von fremden Programmen oder vom Eigenem.
Ist die Datei bereits geöffnet, dann muß der gewünschte Zugriff vom Anderen erlaubt sein.

Die alten Dateifunktionen gewähren nur gleichzeitige Lesezugriffe und es gibt keine (praktikable) Möglichkeit das zu beeinflussen.
Vom RTL-Code her sah es jetzt zwar so aus, als wenn immer Lesezugriffe gewehrt weren, aber beim Schreiben verbiete ich (standardmäßig) selber auch fast immer alle weiteren Zugriffe und beim Lesen verbiete ich Anderen das Schreiben, um konsistente Daten zu gewährleisten. Also wenn das die RTL doch genauso macht und ich es jetzt nur falsch sah, dann würde ich das Verhalten dennoch als richtig betrachten.


Fazit: Dein Programm muß die Zugriffe des anderen Programms gewährleisten und theoretisch könntest du die Datei sogar die ganze Zeit offen lassen.
Aber wenn das andere Programm deine Zugriffe beim Lesen verbietet, dann wirst du damit leben müssen, da du das ja nicht beeinflussen kannst.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PosEx im Delphi viel seltener praktiziert.

Geändert von himitsu (30. Mai 2014 um 20:25 Uhr)
  Mit Zitat antworten Zitat
kkoe

Registriert seit: 6. Mai 2014
3 Beiträge
 
#4

AW: Simultaner Zugriff auf Datei

  Alt 2. Jun 2014, 17:31
Danke Euch beiden, das hat schon mal Hilfe in die richtige Richtung gegeben. Was ich vergessen hatte zu erwähnen, ist dass die Schnittstellen Datei ein XML File ist, und "Rewrite", so schön einfach dieser Ansatz auch aussah, nach meiner Recherche nur bei Textfiles funktioniert?!

Aber ich denke, ich suche genau die Exklusivrechte beim Öffnen einer Datei, die Ihr angesprochen habt. Habe dazu ein kleines Beispiel programmiert, wobei mir diese Exclusivrechte sofort selber auf die Füße gefallen sind. Vlt seht ihr den Fehler.

Delphi-Quellcode:
// Beispiel XML erstellen
procedure TForm1.Button2Click(Sender: TObject);
var
root, c1: IXMLNode;
begin
 count:=0;
 fn:='C:\Temp\Test.xml';
 xml:=TXMLDocument.Create(self);
 xml.Active:=true;
 xml.Version:='1.0';
 xml.Encoding:='UTF-8';
 xml.StandAlone:='no';
 root:=xml.AddChild('ErsterKnoten');
 c1:=root.AddChild('ZweiterKnoten');
 c1.Text:='1';
 xml.XML.Text := FormatXMLData(xml.XML.Text);
 xml.Active:=true;
 xml.SaveToFile(fn);
 xml.Free;
end;

// Timer starten (weil später auch zyklischer Prozess)
procedure TForm1.Button1Click(Sender: TObject);
begin
 Timer1.Enabled:=true;
end;



procedure TForm1.Timer1Timer(Sender: TObject);
begin
 inc(count);
 // Öffnen der zuvor erstellten Datei unter Exklusivrechten
 temp:=FileOpen(fn, fmOpenReadWrite or fmShareExclusive);

 if temp <> -1 then begin

  //hier soll die Datei jetzt bearbeitet werden
  
  xml:=TXMLDocument.Create(self);
  xml.LoadFromFile('C:\Temp\Test.xml');
  xml.ChildNodes.Nodes[1].ChildNodes.Nodes[0].Text:=IntToStr(count);
  Label1.Caption:='Neuer Wert: '+IntToStr(count);
  xml.SaveToFile('C:\Temp\Test.xml');
  xml.Free;
  temp
  FileClose(temp);
 end
 else begin
  Timer1.Enabled:=false;
  ShowMessage('Datei konnte nicht geladen werden');
 end;

end;

end.


Die Fehlermeldung lautet: Datei wird schon von einem anderen Prozess benutzt...
Das Problem liegt wohl darin, dass ich mit LoadfromFile das XML nochmal versuche zu öffnen... aber wie sonst könnte man das XML anderweitig bearbeiten? Danke im Voraus!

Geändert von kkoe ( 2. Jun 2014 um 17:35 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.145 Beiträge
 
Delphi 12 Athens
 
#5

AW: Simultaner Zugriff auf Datei

  Alt 2. Jun 2014, 17:43
Zitat von OH: fmshareexclusive:
Legt eine gemeinsame Dateinutzung fest, die jeglichen Dateizugriff durch andere Anwendungen verhindert.


Zitat:
xml.LoadFromFile('C:\Temp\Test.xml');
Das Problem liegt wohl darin, dass ich mit LoadfromFile das XML nochmal versuche zu öffnen...
Nicht nur vermutlich, sondern bestimmt.

Die Datei nicht exklusiv öffnen, den String auslesen
und dann den XML-"String" an die XML-Komponente übergeben.

Genauso kann man den XML-String erst aus der Komponente rausholen und dann selber in die Datei schreiben.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PosEx im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
kkoe

Registriert seit: 6. Mai 2014
3 Beiträge
 
#6

AW: Simultaner Zugriff auf Datei

  Alt 2. Jun 2014, 18:02
Zitat:
Die Datei nicht exklusiv öffnen, den String auslesen
und dann den XML-"String" an die XML-Komponente übergeben.
Jetzt komm ich nicht mit, welcher ist der String und welcher der XML-"String"(=Filename??)?
Und durch das Weglassen der Exklusivrechte können doch wieder andere Programme auf die Datei zugreifen, während dieses Programm am bearbeiten ist, oder? (Das wollte ich ja verhindern)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.173 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Simultaner Zugriff auf Datei

  Alt 2. Jun 2014, 18:46
Entweder habe ich gravierende Wissenslücken oder, soweit wir hier fest bei Windows sind, macht keiner eine Datei zum Lesen auf wenn da grade reingeschrieben wird. Nicht einmal der gleiche Prozess.
Willst du die Datei ein weiteres mal (zum Lesen) aufmachen muss der Schreibende entweder ein Mapping für die Datei angelegt haben (siehe MSDN: Sharing Files and Memory) oder der lesende ist ein Kindprozess des Schreibenden und kann das Filehandle erben.

Ansonsten, kein Weg. Das hätte ich jetzt spontan behauptet. Wenn das nicht stimmt freue ich mich
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Simultaner Zugriff auf Datei

  Alt 2. Jun 2014, 19:03
Ich hab' mal ne Zeitlang das verwendet, dann aber wieder verworfen. Weiß aber nicht mehr warum?
Delphi-Quellcode:
function FileInUse(const FileName: string): boolean;
var
  Success: Cardinal;
begin
  Result := false;
  if FileExists(FileName) then
  begin
    Success := CreateFile(PChar(FileName),
      GENERIC_READ, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    Result := Success = INVALID_HANDLE_VALUE;
    if not Result then
      CloseHandle(Success);
  end;
end;

procedure Wait50;
var
  ATime: Cardinal;
begin
  ATime := GetTickCount;
  repeat
  until GetTickCount - ATime > 50;
  Application.ProcessMessages;
end;

function CanOpenFile(const FileName: string): boolean;
var
  TryCount: integer;
begin
  Result := true;
  if FileInUse(FileName) then
  begin
    TryCount := 0;
    repeat
      Wait50;
      Inc(TryCount);
      Result := not FileInUse(FileName);
    until Result or (TryCount = 20);
  end;
  if not Result then
    MessageDlg('Zugriff auf ' + FileName + ' verweigert.', mtError, [mbOK], 0);
end;
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.173 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: Simultaner Zugriff auf Datei

  Alt 2. Jun 2014, 19:08
Das versucht ja nur, mittels CreateFile die Datei zum Lesen aufzumachen und sagt, ob dabei INVALID_HANDLE_VALUE herauskam oder nicht. Auf so eine Lösung wird es denke ich ja auch hinauslaufen-

Nur würde ich hierbei bemängeln dass die Wahrscheinlichkeit zwar wahrscheinlich hoch, aber nicht garantiert ist dass du deine öffnen kannst nachdem das Prüfen einmal meinte, man könne sie zum Lesen öffnen: Zwischen Prüfen und Aufmachen kann sie sich ja schon wieder jemand anders geschnappt haben- Die Gegenseite könnte beispielsweise wieder anfangen zu schreiben.
  Mit Zitat antworten Zitat
Bjoerk

Registriert seit: 28. Feb 2011
Ort: Mannheim
1.384 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Simultaner Zugriff auf Datei

  Alt 2. Jun 2014, 19:24
Kann sein. Prüfte glaub ich GENERIC_READ or GENERIC_WRITE usw. Weiß nicht mehr so genau?
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:52 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz