Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi nicht exklusiver Zugriff mit CreateFile erwünscht (https://www.delphipraxis.net/136213-nicht-exklusiver-zugriff-mit-createfile-erwuenscht.html)

VizeTE 25. Jun 2009 18:14


nicht exklusiver Zugriff mit CreateFile erwünscht
 
Hallo,

ich habe vor kurzem die Funktion "CreateFile" und das Flag "FILE_FLAG_DELETE_ON_CLOSE" entdeckt. Wenn ich das richtig verstanden habe erzeugt mir CreateFile eine Datei die dann automatisch gelöscht wird wenn ich das erhaltene Handle schließe oder die Anwendung geschlossen wird.
Soweit so gut.

Ich möchte jetzt also so ein Datei erstellen, füllen und dann an anderer Stelle in ein Blobfeld speichern. Beim speichern bekomme ich dann aber immer die Fehlermeldung das die Datei nicht geöffnet werden kann.

So habe ich das gemacht:
Delphi-Quellcode:
        //Filename enthält schon den gewünschten Pfad und Dateinamen
        Hnd := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE,
                          FILE_SHARE_DELETE or FILE_SHARE_READ or FILE_SHARE_WRITE,
                          nil, CREATE_ALWAYS,
                          FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE, 0);
        ...
        hHdlStream := THandleStream.Create(Hnd);
        hHdlStream.Write(oMemStream, oMemStream.Size); //oMemStream enthält die zu schreibenden Daten
        hHdlStream.Free;

        SendFile(FileName); //hier kommt der Fehler wenn ich "LoadFromFile" aufrufe

        CloseHandle(Hnd);
Kann das überhaupt funktionieren? Falls ja was mache ich falsch? Gibt es bessere Alternativen?

SimStar001 25. Jun 2009 18:49

Re: nicht exklusiver Zugriff mit CreateFile erwünscht
 
wenn ich das richtig sehe, erstellst du die datei dann in nem Stream.
lade die datei einfach mal aus dem stream heraus, bevor du Ihn wieder freigibst

himitsu 25. Jun 2009 19:09

Re: nicht exklusiver Zugriff mit CreateFile erwünscht
 
LoadFromFile du könntest dir ja LoadFromFile überschreiben und Daß dort kein exclusiver Zugriff erfolgt.

Oder du verwendest in SendFile LoadFromStram und verwendest entweder gleich den vorhergehenden Strem, bzw. erstellst einen eigenen für's Senden.

VizeTE 26. Jun 2009 09:53

Re: nicht exklusiver Zugriff mit CreateFile erwünscht
 
Zitat:

Zitat von himitsu
LoadFromFile du könntest dir ja LoadFromFile überschreiben und Daß dort kein exclusiver Zugriff erfolgt.

Ich habe folgendes getestet, leider ohne Verbesserung:
Delphi-Quellcode:
oFileStream := TFileStream.Create(sTmpFile, fmOpenRead or fmShareDenyNone);
Zitat:

Zitat von himitsu
Oder du verwendest in SendFile LoadFromStram und verwendest entweder gleich den vorhergehenden Strem, bzw. erstellst einen eigenen für's Senden.

Ja, mit einem weiteren THandleStream gehts. Es ist für mich aber sehr umständlich wenn ich die sendende Funktion umstellen muß. Ich hatte gehofft das ich die Datei auch mit einem TFileStream öffnen kann, selbst wenn ich an andere Stelle das Handle noch habe. Schließlich habe ich doch alle möglichen FILE_SHARE_... angegeben.
Wenn das nicht möglich ist dann kann ich diese automatisch-löschen-Funktionalität nicht verwenden.

Fridolin Walther 26. Jun 2009 10:34

Re: nicht exklusiver Zugriff mit CreateFile erwünscht
 
Ich mein, offensichtlich hast Du ja schon mal in die Doku geguckt, sonst wüsstest Du von dem Flag ja nichts. Der zweite Schritt wäre jetzt, nicht nach dem ersten Satz neben dem Flag aufhören zu lesen, dort steht nämlich:

Zitat:

The file is to be deleted immediately after all of its handles are closed, which includes the specified handle and any other open or duplicated handles.
If there are existing open handles to a file, the call fails unless they were all opened with the FILE_SHARE_DELETE share mode.
Subsequent open requests for the file fail, unless the FILE_SHARE_DELETE share mode is specified.
Bedeutet: Dein Filestream muss die Datei ebenfalls mit FILE_SHARE_DELETE öffnen, ansonsten wird der Zugriff verweigert. Dazu müsstest Du Dir imho allerdings eine eigene TFileStream Klasse ableiten. Ansonsten versteh ich nicht, wieso Du nicht einfach ein HandleStream verwendest. Du kannst ja durchaus weiterhin eine überladene SendFile Funktion anbieten, die einen Dateinamen akzeptiert, mit CreateFile ein Handle erzeugt und dann die SendFile Variante mit Handle aufruft.

VizeTE 29. Jun 2009 09:24

Re: nicht exklusiver Zugriff mit CreateFile erwünscht
 
Zitat:

Zitat von Fridolin Walther
Dein Filestream muss die Datei ebenfalls mit FILE_SHARE_DELETE öffnen

Das ist ein guter Tipp. Ich hatte mich auf die Doku von Delphi beschränkt, aber auch da hätte man das rauslesen können.
Nunja...damit bin ich in Stück weiter gekommen aber leider auch noch nicht am Ziel.

Ich habe einfach als Basis einen THandleStream verwendet und dann ein eigenes Create (ab)geschrieben.
Dabei habe ich bisher nur das öffnen einer bestehenden Datei geändert um zunächst testen zu können.
Jetzt bekomme ich keine Fehlermeldung mehr aber der Inhalt ist einfach Schrott.
(die Dateigröße bleibt gleich, der Inhalt sieht aber wie Speichermüll aus)
Sieht jemand meinen Fehler? ich habe Tomaten auf den Augen.

Delphi-Quellcode:
constructor TMyFileStream.Create(const FileName: string; Mode: Word);
var
  hFile : integer;
begin
  if Mode = fmCreate then
  begin
    hFile := FileCreate(FileName);
    if hFile < 0 then
      raise EFCreateError.CreateResFmt(@SFCreateError, [FileName]);
  end else
  begin
    hFile := integer(CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE,
             FILE_SHARE_DELETE or FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING,
             FILE_ATTRIBUTE_NORMAL, 0));
    if hFile < 0 then
      raise EFOpenError.CreateResFmt(@SFOpenError, [FileName]);
  end;

  inherited Create(hFile);
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz