Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Datei öffnen, die von einem anderen Prozess benutzt wird (https://www.delphipraxis.net/151438-datei-oeffnen-die-von-einem-anderen-prozess-benutzt-wird.html)

oki 18. Mai 2010 08:01


Datei öffnen, die von einem anderen Prozess benutzt wird
 
Hallo Leute,

trotz Suche bin ich nicht weiter. Ich will eine Datei öffnen, in die ein anderes Programm Daten schreibt um diese sofort (während der Messung) zu lesen. Jetzt bekomme ich immer die Meldung, dass die Datei nicht geöffnet werden kann, da sie von einem anderen Prozess verwendet wird.

Ich versuche die Datei so zu öffnen:
Delphi-Quellcode:
procedure TLTC2440_DataList.LoadData(AFileName: String);
var AFStream : TFileStream;
    ASStream : TStringStream;
begin
  FFileName := AFileName;
  Clear;

  if not FileExists(AFileName) then
    Exit;
  FFileText := TStringList.Create;
  AFStream := TFileStream.Create(AFileName, fmOpenRead, fmShareDenyNone);
  try
    ASStream := TStringStream.Create;
    try
      ASStream.LoadFromStream(AFStream);
      FFileText.Text := ASStream.DataString;
    finally
      FreeAndNil(ASStream);
    end;
  finally
    FreeAndNil(AFStream);
  end;
  try
    DecodeHeaderfromFile(FFileText);
    DecodeValues(FFileText);
  finally
    FreeAndNil(FFileText);
  end;
end;
Vorher hatte ich es erst nur über die TStringList mit LoadfromFile versucht. Kein Erfolg. Wenn ich die Datei mit dem Windows-Editor öffne gibt es keine Fehlermeldung. Also mache ich was falsch. Die Frage ist nur was?

Ich hoffe auf eure Hilfe,

Gruß oki

himitsu 18. Mai 2010 08:16

Re: Datei öffnen, die von einem anderen Prozess benutzt wird
 
TFileStream (wird auch bei LoadFromFile in TStrings/TStringList) verwendet, läßt beim Auslesen nur Lesezugriffe anderer Anwendungen zu.
Diese Datei ist bei dir aber im Schreibzugriff geöffnet.

Lösung: THandleStream + MSDN-Library durchsuchenCreateFile und dort fremde Schreibrechte erlauben
(ShareMode = FILE_SHARE_READ or FILE_SHARE_WRITE) und dann TStringList+LoadFromStream
(bei TFileStream fehlt das FILE_SHARE_WRITE ... so wird sichergestellt, daß eine Datei nicht wärend des Lesen verändert wird und somit die Daten konsistent bleiben)

PS: TStringStream hättes du nicht benötigt, da TStringList auch ein LoadFromStream kennt und somit die Daten unnötiger Weise umherkopiert werden. :zwinker:

oki 18. Mai 2010 08:27

Re: Datei öffnen, die von einem anderen Prozess benutzt wird
 
Hi himitsu,

Dank für den Lösungsansatz und deinen Hinweis. Ich teste das aus und melde mich.

Gruß oki

Luckie 18. Mai 2010 09:15

Re: Datei öffnen, die von einem anderen Prozess benutzt wird
 
Das funktioniert aber nur, wenn das andere Programm auch von ihm ist und er den Code entsprechend anpassen kann. Wenn ein anderer Prozess eine Datei exklusiv für sich öffnet, dann ist sie eben exklusiv geöffnet.

himitsu 18. Mai 2010 09:27

Re: Datei öffnen, die von einem anderen Prozess benutzt wird
 
Zitat:

Zitat von Luckie
Wenn ein anderer Prozess eine Datei exklusiv für sich öffnet, dann ist sie eben exklusiv geöffnet.

Dann dürfte Notepad es auch nicht lesen können.

Der andere Prozess scheint also die nötigen Sharing-Rechte (zumindestens zum Lesen) zu geben.
Allerdings hat der andere Prozess die Datei eben schon zum Schreiben geöffnet, welches halt von TFileString nicht erlaubt wird.

Aber im Prinzip hast du Recht.
Wenn der andere Prozess keine Sharing-Rechte freigibt, dann ist das eben so.
Wenn mehrere Prozesse auf die selbe Datei zugeifen wollen/müssen, dann müssen die entsprechenden Sharing-Rechte auch zusammenpassen ... ansonsten: Wer zuerst kommt, der ließt/schreib zuerst und der Ander hat das Nachsehn.

Luckie 18. Mai 2010 09:30

Re: Datei öffnen, die von einem anderen Prozess benutzt wird
 
OK, das mit dem Notepad hatte ich überlesen. Dann liegt es wirklich nur an seinem Code.

oki 18. Mai 2010 12:29

Re: Datei öffnen, die von einem anderen Prozess benutzt wird
 
Hi Leute,

sorry, dass es so lange gedauert hat. Lag aber nicht an den paar Zeilen, musste noch einige andere Probleme lösen.
Himitsu hat das richtig erkannt. Ich habe meinen Code wie folgt angepasst:
Delphi-Quellcode:
procedure TLTC2440_DataList.LoadData(AFileName: String);
var AHStream : THandleStream;
    AFileHandle : THandle;
begin
  FFileName := AFileName;
  Clear;

  if not FileExists(AFileName) then
    Exit;
  AFileHandle := INVALID_HANDLE_VALUE;
  AFileHandle := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
    0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

  if AFileHandle <> INVALID_HANDLE_VALUE then begin
    FFileText := TStringList.Create;
    try
      try
        AHStream := THandleStream.Create(AFileHandle);
        try
          FFileText.LoadFromStream(AHStream);
        finally
          FreeAndNil(AHStream);
        end;
      finally
        CloseHandle(AFileHandle);
      end;
      DecodeHeaderfromFile(FFileText);
      DecodeValues(FFileText);
    finally
      FreeAndNil(FFileText);
    end;
  end;
end;
Damit ist das Problem vom Tisch. Nochmals herzlichen Dank für den Tip.
@Luckie: Ja, meine Bemerkung mit "Exclusive" war etwas vorschnell und nicht unbedingt korrekt. Hatte aus diesem Grund auch den Hinweis mit dem Editor angefügt. Aber im Grunde hat himitsu mich richtig verstanden.

Dank an alle und Gruß

oki

himitsu 18. Mai 2010 12:41

Re: Datei öffnen, die von einem anderen Prozess benutzt wird
 
Delphi-Quellcode:
procedure TLTC2440_DataList.LoadData(AFileName: String);
var AHStream : THandleStream;
    AFileHandle : THandle;
begin
  FFileName := AFileName;
  Clear;
  AFileHandle := CreateFile(PChar(AFileName), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
    0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  if AFileHandle <> INVALID_HANDLE_VALUE then begin
    FFileText := TStringList.Create;
    try
Im Prinzip kannst'e das noch etwas kürzen.
OPEN_EXISTING beinhaltet ja quasi schon das FileExists.

oki 18. Mai 2010 13:49

Re: Datei öffnen, die von einem anderen Prozess benutzt wird
 
Joop, hast Recht. Das sind die bekannten Überbleibsel beim Code ändern. Einfach nicht drauf geachtet.

Dank und Gruß

oki


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:23 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