Seite 1 von 1

Überprüfen ob eine Datei fertig geschrieben / kopiert wurde

Verfasst: 05.09.2008 17:30
von WHEEZ
HI,
Ich möchte ein Verzeichnis auf Veränderungen / neue Dateien überwachen. Wenn eine Datei mit einer bestimmten Endung in dem Ordner landet, möchte ich diese z.B. mit einem anderen Programm öffnen. Klappt alles auch schon recht gut - nur bei größeren Dateien und vor allem beim Kopieren übers LAN kommt es vor dass Aktionen schon ausgeführt werden bevor die Datei vollständig kopiert wurde.
Wie kann ich am besten feststellen ob eine Datei "fertig" ist? Momentan mache ich es in einem Loop der mit FileSize() vergleicht ob sich die Größe noch ändert und wenn sich eine bestimmte Zeit nichts mehr tut, löse ich die Akltion aus. Nur muss ich da teilweise recht große Intervalle (5 Sekunden und mehr) einstellen damit diese Methode einigermaßen geht... das Gelbe vom Ei ist das nicht.
Gibt es da eine elegantere Möglichkeit?

Gruß und Thx,
WHEEZ

Re: Überprüfen ob eine Datei fertig geschrieben / kopiert wu

Verfasst: 05.09.2008 19:02
von michel51
WHEEZ hat geschrieben:HI,
Ich möchte ein Verzeichnis auf Veränderungen / neue Dateien überwachen. Wenn eine Datei mit einer bestimmten Endung in dem Ordner landet, möchte ich diese z.B. mit einem anderen Programm öffnen. Klappt alles auch schon recht gut - nur bei größeren Dateien und vor allem beim Kopieren übers LAN kommt es vor dass Aktionen schon ausgeführt werden bevor die Datei vollständig kopiert wurde.
Wie kann ich am besten feststellen ob eine Datei "fertig" ist? Momentan mache ich es in einem Loop der mit FileSize() vergleicht ob sich die Größe noch ändert und wenn sich eine bestimmte Zeit nichts mehr tut, löse ich die Akltion aus. Nur muss ich da teilweise recht große Intervalle (5 Sekunden und mehr) einstellen damit diese Methode einigermaßen geht... das Gelbe vom Ei ist das nicht.
Gibt es da eine elegantere Möglichkeit?

Gruß und Thx,
WHEEZ
Wie wäre mit einem Checksummentest über die "fertige" Datei?
Wenn du eine Datei abschicken willst, erstelle eine Checksumme (dafür gibt es reichlich Beispiele und so in PB), und am anderen Ende prüfe die Checksumme. Dann weißt du, wenn beide übereinstimmen, dass die Datei unverändert angekommen ist. Eine Änderung der Datei verändert die Checksumme und damit kannst du entsprechend reagieren.
Leider kenne ich mich damit zu wenig aus, um ein Beispiel zu posten.
Aber such mal im Forum, in der Hilfe oder im Archiv. Da wirst du sicher fündig werden.

Verfasst: 05.09.2008 19:05
von WHEEZ
Das Problem ist nur das ich nichts vom "Abschicken" mitbekommen - ich weiß nicht welche Dateien und wie die aussehen....

Verfasst: 06.09.2008 10:02
von michel51
WHEEZ hat geschrieben:Das Problem ist nur das ich nichts vom "Abschicken" mitbekommen - ich weiß nicht welche Dateien und wie die aussehen....
Hmm... das sieht so nach automatischer Ordnersynchronisation aus. Da kann ich auch nicht weiterhelfen. Aber ich denke, "abschicken" und "empfangen" sollten detektiert werden können. Denn wenn ich richtig verstanden habe, hast du keine Kontrolle darüber, WANN etwas abgeschickt wird. Vielleicht kann ja einbe Windows-API helfen....
Vermutlich ist der einfachste Weg, den "Empfangsordner" zu überwachen. Das heißt, wenn sich hier was ändert, entsprechend zu reagieren. Also die Inhalte vorher-nachher vergleichen. Vielleicht gibt es ja auch dafür Windows_APIs, die derartiges tun. Da kenne ich mich aber gar nicht aus.

Vielleicht liege ich aber auch völlig falsch.. :?

Verfasst: 06.09.2008 14:46
von WHEEZ
Ja - danach suche ich. Genau geht es um einen Ordner im Netzwerk der von mehreren Rechnern über diverse Verbindungen (auch von extern) zugänglich ist. Wenn jetzt irgendjemand eine Datei in den Ordner kopiert, soll mit der Datei je nach Typ etwas passieren - z.B. verschoben werden, per Mail verschickt werden, entpackt oder sonst was. Dafür muss ich aber wissen wann eine Datei vollständig ist.

Verfasst: 06.09.2008 18:38
von dige
Du musst zunächst den Datei-Typ ermitteln. Für die meisten Formate gibt
es einen Datei Anfang und Ende Marker. Wobei in Deinem Fall vor allem
der Ende Marker relevant sein dürfte.
Eine JPEG Datei beginnt zum Bsp. mit $FF D8 und endet mit $FF D9
Am besten mal bzgl. der Datenformat http://www.wotsit.org/ checken..

Oder eine neue Datei ein bestimmtes Zeitintervall überwachen ob sich die Dateigröße noch ändert...

Verfasst: 06.09.2008 20:35
von michel51
dige hat geschrieben: Oder eine neue Datei ein bestimmtes Zeitintervall überwachen ob sich die Dateigröße noch ändert...
So ähnlich meinte ich es.
Den Empfangsordner überwachen, ob sich was ändert, checken was sich getan hat (welche Datei oder Dateityp angekommen ist), eine "Zeitbremse" einbauen, um sicher zu gehen, dass die Datei auch wirklich komplett ist (wie es ja schon gemacht wird), und dann - eventuell noch nach einer Sicherheitspause - die für diesen Dateityp geforderte Aktion auslösen.
Es kommt bei diesem Automatismus sicher nicht auf ein paar (Milli-)Sekunden an, ich denke, die Sicherheit bzw. sichere Ausführung geht vor.

Verfasst: 06.09.2008 22:49
von Thorium
Schau dir mal das hier an. In wie weit man damit auch feststellen kann ob eine Datei komplett kopiert wurde weis ich jetzt nicht. Wäre aber z.b. möglich das die Change Size Notification oder Create Notification nur einmal auftritt, wenn die Datei komplett kopiert wurde. Müsstest es mal ausprobieren, ich hab damit noch nie gearbeitet.

Verfasst: 06.09.2008 23:58
von AND51
michel51 hat geschrieben:
dige hat geschrieben: Oder eine neue Datei ein bestimmtes Zeitintervall überwachen ob sich die Dateigröße noch ändert...
So ähnlich meinte ich es.
Vielleicht gibt es ja noch eine Lösung mit PB-nativen Befehlen:

Ich habe letztens eine 4 GB Datei übers Netzwerk kopiert; im Explorer des Empfängers stand die komplette Dateigröße, obwohl das Kopieren ca. 2 Minuten gedauert hat.

Demnach liefert FileSize() immer einen festen Wert - nämlich die finale Größe der Datei.
Schön mal über das Öffnen der Datei nachgedacht? Was liefert denn Lof()? Kann ja wohl nicht die finale Endgröße liefern, weil die Datei ja noch fertig geschrieben wurde. Versuch doch also mal folgendes: Öffne Die Datei in einer Schleife ständig; solange, bis Lof()=FileSize():

Code: Alles auswählen

Procedure WaitForFile(File$) ; 0=Error (cannot read), 1=success
   Protected id, size.q=FileSize(File$)
   While size >= 0
      id=ReadFile(#PB_Any, File$)
      If id
         If Lof(id) = size
            CloseFile(id)
            ProcedureReturn 1
         Else
            CloseFile(id)
         EndIf
      Else
         Break
      EndIf
      Delay(500)
   Wend
EndProcedure
Die Prozedur müsste -wenn die zugrundeliegende Idee korrekt ist- erst fertig gelaufen sein, wenn die Datei komplett geschrieben wurde. Gibt 0 zurück, wenn die Datei nicht geöffnet werden konnte.

Verfasst: 07.09.2008 07:17
von Bisonte
Also wenn ich Dateien im Lan Kopiere, ist die Filegrösse stetig am wachsen.
Und wenn man versuch das File zu öffnen gibts eine Fehlermeldung, von
wegen Datei in Benutzung...