Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Zugriffsfehler bei Kopiervorgang (https://www.delphipraxis.net/173249-zugriffsfehler-bei-kopiervorgang.html)

bAlaRk 14. Feb 2013 10:45

Zugriffsfehler bei Kopiervorgang
 
Hallo Leute,

ich habe folgendes Problem. Mein Programm sieht zyklisch alle 2 Minuten in einem Verzeichnis nach ob neue Daten vorhanden sind und importiert sie gegebenenfalls in eine Dokumentenverwaltungssoftware. Das Verzeichnis ist das Zielverzeichnis des Scanners, der also per FTP upload pdfs da rein schiebt. Der worst case tritt ein wenn gerade gescannt wird, die 2 Minuten rum sind und die Software während dem Uploadvorgang losrennt, dann gibts nen crash:
"Beim Zugriff auf den Datenträger ist ein Fehleraufgetreten: Datei Pfad\xy.pdf kann nicht geöffnet werden. Der Prozess kann nicht auf die Datei zugreifen, da sie von einem anderen Prozess verwendet wird. / Der Vorgang wurde erfolgreich beendet(0)."

Um den Fragen hast du schon mal im Forum gesucht oder gegoogelt gleich vorweg auszuweichen, ja hab ich!

Folgendes habe ich probiert:
Delphi-Quellcode:
function IsFileInUse(const fName: TFileName): Boolean;
var
  HFileRes: HFILE;
begin
  Result := False;
  HFileRes := CreateFile(PChar(fName),
                         GENERIC_READ or GENERIC_WRITE,
                         0,
                         nil,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         0);
  Result := (HFileRes = INVALID_HANDLE_VALUE);
  if not Result then
    CloseHandle(HFileRes);
end;
und hier aus dem Forum folgende Lösung:
Delphi-Quellcode:
function IsFileOpen(const FileName: string): Boolean;
var Stream: TFileStream;
begin
  Result := false;
  if not FileExists(FileName) then exit;
  try
    Stream := TFileStream.Create(FileName,fmOpenRead or fmShareExclusive);
  except
    Result := true;
    exit;
  end;
  Stream.Free;
end;
Leider wird mir nicht angezeigt, dass die Datei wie auch immer verwendet wird, mit anderen Worten die Rückgabe ist immer false, obwohl die Datei definitiv nicht vollständig angekommen ist.

Ich muss zu meiner Schande gestehen, dass ich eigentlich nur wenns wirklich nicht anders geht in Delphi programmiere und damit bei spezifischen Themen mehr ein copy/paste Delphi Coder bin. Vielleicht weiss einer von euch Rat,

Danke schon Mal, bAlaRk

p80286 14. Feb 2013 11:25

AW: Zugriffsfehler bei Kopiervorgang
 
Ich habe da ein Verständnisproblem
Zitat:

Zitat von bAlaRk (Beitrag 1203459)
Leider wird mir nicht angezeigt, dass die Datei wie auch immer verwendet wird, mit anderen Worten die Rückgabe ist immer false, obwohl die Datei definitiv nicht vollständig angekommen ist.

IsFileOpen kommt mit True zurück wenn eine existierende Datei für das exclusive Lesen gespert ist.
in allen anderen Fällen, Datei ist lesbar oder Datei ist nicht vorhanden, kommt false zurück.
Die Vollständigkeit der Datei läßt sich damit nicht überprüfen.

Gruß
K-H

CCRDude 14. Feb 2013 11:37

AW: Zugriffsfehler bei Kopiervorgang
 
Vielleicht als Tipp: verzichte auf das Pollen, verwende MSDN-Library durchsuchenFindFirstChangeNotification, MSDN-Library durchsuchenReadDirectoryChangesW, MSDN-Library durchsuchenFindNextChangeNotification. Mit dessen Benachrichtigungen solltest Du den richtigen Zeitpunkt nach dem Schreiben afaik erwischen.

bAlaRk 14. Feb 2013 11:45

AW: Zugriffsfehler bei Kopiervorgang
 
@ p80286:

Wenn das Programm läuft und der Upload Prozess noch nicht abgeschlossen ist, dann kommt der die Fehlermeldung, dass die Datei noch von einem anderen Prozess genutzt wird(Upload).
Was ich möchte ist eine Funktion die mir mitteilt ob ich auf die Datei zugreifen kann ohne diese Konflikt auszulösen. Wenn nicht, dann soll das Programm die DAtei einfach auslassen und im nächsten SChwung mit importieren.
Beide Methoden, die ich verwendet habe liefern immer false zurück, also nicht offen bzw nicht in use. Sind aber offensichtlich in Benutzung, weil kurz darauf die Fehlermeldung fliegt wenn ich versuche die Datei unfertig(also nicht vollständig hochgeladen und damit in Benutzung des Uploadprozesses) in meine Software zu importieren.
Ich habe angenommen, dass mir spätestens die Methode isInUse ein true in dem Fall zurück gibt, aber leider tut es das nicht.

@CCRDude:

Das war mein erste Ansatz, immer dann zu schreiben wenn eine neue Datei da ist, aber das habe ich nicht hinbekommen(:pale:) und danach auf den zeitgesteuerten umgeschwenkt:oops:...

Sir Rufo 14. Feb 2013 11:57

AW: Zugriffsfehler bei Kopiervorgang
 
@bAlaRk

Um das mit einfachen Mitteln und ohne viel Aufwand zu beheben, mach doch einfach folgendes:

Immer wenn du das Verzeichnis scannst, suche den Dateinamen in einer
Delphi-Quellcode:
TStringList
.
  1. Ist der Dateiname dort nicht vorhanden, dann schreibe diesen dort hinein.
  2. Ist der Dateiname dort vorhanden, dann entferne diesen Eintrag und kopiere die Datei.
Wenn du jetzt alle 2 Minuten schaust, dann wird eine neue Datei beim ersten Lauf in die
Delphi-Quellcode:
TStringList
geschrieben, aber noch nicht kopiert.
Beim nächsten Lauf wird der Dateiname in der
Delphi-Quellcode:
TStringList
gefunden und folglich erst jetzt kopiert.

Nach 2 Minuten sollte der Upload der Datei per FTP ja wohl erledigt sein und die Häufigkeit der Ausnahmen ist schon mal erheblich verringert.

Das Kopieren selber solltest du auch in einem
Delphi-Quellcode:
try .. except
Block erledigen.Die Exceptions werden davon gefangen dein Programm bleibt auch nicht hängen.
Delphi-Quellcode:
try
 
  // hier der Code zum Kopieren der Datei

except
  on E: Exception do
    begin
      // hier könnte ein Code sein, um diese Fehlermeldung in einem Log zu speichern
    end;
end;
Es ist natürlich nicht die beste Lösung (wegen Pollen) aber eine für dich leicht umsetzbare und darauf kommt es am Ende immer an :)

BTW: Es sollte für dein Programm sogar ausreichen, die Exception mit dem
Delphi-Quellcode:
try .. except
zu fangen

DeddyH 14. Feb 2013 12:30

AW: Zugriffsfehler bei Kopiervorgang
 
Wenn man eh schon pollt, könnte man dann nicht auch die Dateigröße vergleichen? So nach dem Motto: wenn die seit 10 Sekunden unverändert ist, dürfte der Schreibvorgang abgeschlossen sein.

Sir Rufo 14. Feb 2013 12:34

AW: Zugriffsfehler bei Kopiervorgang
 
Zitat:

Zitat von DeddyH (Beitrag 1203505)
Wenn man eh schon pollt, könnte man dann nicht auch die Dateigröße vergleichen? So nach dem Motto: wenn die seit 10 Sekunden unverändert ist, dürfte der Schreibvorgang abgeschlossen sein.

Dürfte ist genau richtig aber eben nicht eindeutig, darum ist das Fangen der Exception eh Pflicht und dann kann man es sich auch sparen ;)

p80286 14. Feb 2013 12:38

AW: Zugriffsfehler bei Kopiervorgang
 
Zitat:

Zitat von DeddyH (Beitrag 1203505)
Wenn man eh schon pollt, könnte man dann nicht auch die Dateigröße vergleichen? So nach dem Motto: wenn die seit 10 Sekunden unverändert ist, dürfte der Schreibvorgang abgeschlossen sein.

Nach meiner Erfahrung geht das warum auch immer in die Hose,da manche Kopiervorgänge lt. Anzeige im Explorer sehr ungleichmäßig verlaufen. :?:

Gruß
K-H

DeddyH 14. Feb 2013 12:38

AW: Zugriffsfehler bei Kopiervorgang
 
Zitat:

Zitat von Sir Rufo (Beitrag 1203507)
dann kann man es sich auch sparen ;)

Das sehe ich ein wenig anders (jede vermiedene Exception ist eine gute Exception), aber bevor das jetzt ausartet...


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