Forum: PC-Programmierung Kopiervorgang erkennen vb.net


von Marco G. (grmg2010)


Lesenswert?

Moin,

ich versuche einen art upload ordner zu erstellen, d.h. eine Datei wird 
hineinkopiert und dann automatisch erkannt und in einen anderen Ordner 
überführt.

Die wollte ich das Auslösen eines FileWatcher-Events triggern. Die 
erkennung klappt, aber leider nicht die erkennung, ob die Datei bereit 
vollständig im Ordner liegt. Während des Kopiervorganges, kann ich diese 
natürlich nicht weiterkopieren.

Meine Idee war es, die Dateigröße abzufragen, da sich diese während des 
Kopiervorganges ja ändern muss. Ändert sie sich nicht mehr, ist der 
Vorgang abgeschlossen. Nur leider weiß ich nicht genau, wie ich dies 
realisieren soll. Ich bekomme immer nur die Dateilänge, nicht die 
aktuellen Bytes.

Hat jemand eine Idee, wie man dies in VB.NET lösen könnte?

Gruß

von Ich (Gast)


Lesenswert?

Kann man über die Windows Api nicht herausbekommen, ob noch ein Handle 
auf der Datei ist?
Ist zwar nicht ganau das was du gesucht hast, aber besser als nichts.

von Jim M. (turboj)


Lesenswert?

Ich schrieb:
> Kann man über die Windows Api nicht herausbekommen, ob noch ein Handle
> auf der Datei ist?

Ganz simpel: Datei öffnen. Per default werden Dateien exclusiv geöffnet 
- oder halt nicht wenn sie jemand anders offfen hat.

Die "shared" Flags für nicht-exclusiven Zugriff müsste man manuell 
angeben.

von Mario M. (thelonging)


Lesenswert?

Wenn der Zugriff auf die Datei fehlschlägt, gibt es ja eine Exception. 
Dann trägst Du die Datei in eine Liste ein und über einen Timer 
gesteuert wiederholst Du das Ganze.

von Marco G. (grmg2010)


Lesenswert?

Ich dachte an das aufrufen dieser Funktion in einer Schleife.
1
Public Function FileInUse(ByVal sFile As String) As Boolean
2
    If System.IO.File.Exists(sFile) Then
3
        Try
4
            Dim F As Short = FreeFile()
5
            FileOpen(F, sFile, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.LockReadWrite)
6
            FileClose(F)
7
        Catch
8
            Return True
9
        End Try
10
    End If
11
End Function

von georg (Gast)


Lesenswert?

Marco G. schrieb:
> aber leider nicht die erkennung, ob die Datei bereit
> vollständig im Ordner liegt

Du versuchst, sie exklusiv zu öffnen. Das klappt erst wenn der 
Kopiervorgang abgeschlossen ist. Marcos Beispiel sollte ok sein, 
überprüft habe ich das nicht.

Georg

von c-hater (Gast)


Lesenswert?

georg schrieb:

> Du versuchst, sie exklusiv zu öffnen. Das klappt erst wenn der
> Kopiervorgang abgeschlossen ist.

Das ist leider nicht notwendigerweise der Fall. Es kommt natürlich 
darauf an, wie der kopierende Prozess die Datei geöffnet hat. 
Prinzipiell steht es diesem Prozess frei, die Datei auch mit 
irgendwelchen Share-Parametern zu öffnen.

Und die Erfahrung sagt: Wenn irgendwas prinzipiell möglich ist, wird es 
füher oder später auch passieren. Man ist also gut beraten, das eigene 
Programm so zu schreiben, dass es auch im worst case fehlerfrei 
funktioniert.

Der Weg dahin führt über die Eventfilter des Filesystemwatchers. Man ist 
gut beraten, erstmal zu lernen, wann genau die einzelnen Events 
erfolgen. Die Doku ist in dieser Hinsicht leider völlig Banane, also 
muss man das selber "ausklingeln". Dazu kann man ganz gut robocopy 
verwenden, mit dessen vielen Optionen kann man fast alles testen, was 
beim Schreiben passieren kann.

Doch auch die kompetente Nutzung des Eventfilters löst nicht alle 
Probleme. Ein Exception-Handler und eine timerbasierte Helper-Routine 
zum "Bereinigen" fehlgeschlagener Zugriffe bleibt leider trotzdem 
unumgänglich.

von never ever (Gast)


Lesenswert?

wozu schuff billyboy die attribute ??

von Marco G. (grmg2010)


Lesenswert?

never ever schrieb:
> wozu schuff billyboy die attribute ??

Auf welche Attribute beziehst du dich genau? Ich hatte auch überlegt 
über die Attribute zu gehen, mit denen des letzten Schreibzugriffes. Hat 
aber auch nicht zufriedenstellend funktioniert.

Meine Funktionierende Lösung ist im Moment dieses hier:

Marco G. schrieb:
> Ich dachte an das aufrufen dieser Funktion in einer Schleife.
> Public Function FileInUse(ByVal sFile As String) As Boolean
>     If System.IO.File.Exists(sFile) Then
>         Try
>             Dim F As Short = FreeFile()
>             FileOpen(F, sFile, OpenMode.Binary, OpenAccess.ReadWrite,
> OpenShare.LockReadWrite)
>             FileClose(F)
>         Catch
>             Return True
>         End Try
>     End If
> End Function

Das in einem Timer aufgerufen und Exzeption behandelt funktioniert sehr 
gut. Fehlerbehandlung gibt es auch. Nächster Schritt ist, mehrere 
Dateien zu verarbeiten, die gleichzeitig in den Ordner kopiert werden.

von georg (Gast)


Lesenswert?

c-hater schrieb:
> Prinzipiell steht es diesem Prozess frei, die Datei auch mit
> irgendwelchen Share-Parametern zu öffnen.

Kann er, aber das ändert nichts dran, dass man sie nicht öffen kann, 
wenn man sie selber exklusiv haben will. Sonst wäre die Forderung 
"Exklusiv" ja völlig sinnfrei.

Georg

von c-hater (Gast)


Lesenswert?

georg schrieb:

> Kann er, aber das ändert nichts dran, dass man sie nicht öffen kann,
> wenn man sie selber exklusiv haben will. Sonst wäre die Forderung
> "Exklusiv" ja völlig sinnfrei.

Da hast du vollkommen Recht. Trotzdem beharre ich auf meiner Darstellung 
des Problems (und der sinnvollen Abhilfen).

Scheinbar habe ich das (im Unterschied zu dir) tatsächlich schonmal 
gemacht und ordentlich ausgetestet... Und dabei meine Lektion gelernt...

Tipp: Exklusiver Dateizugriff ist unter Windows nicht wirklich exklusiv. 
Geschützt wird dadurch nur der Inhalt der Datei und, als einziger 
Metadateneintrag, der Größeneintrag im Verzeichnis, nicht aber alle 
sonstigen Metadaten einer Datei...

Und: Die Ereignisse des Filesystemwatchers behandeln ausschließlich die 
Änderungen an Metadaten, nicht die an der Datei selber...

Wird dir jetzt langsam klar, auf was du dich da einläßt...

von georg (Gast)


Lesenswert?

c-hater schrieb:
> Wird dir jetzt langsam klar, auf was du dich da einläßt...

Meinst du jetzt auf Dateiebene, oder mit dir als führender 
Fäkalienschleuder? Weder noch, ich bin ja auch nicht der TO, ich habe es 
nur gewagt dir in einem technischen Punkt zu widersprechen. Für dich ist 
das wohl Insubordination, aber das ist mir sowas von egal.

Georg

von Mr. Big (Gast)


Lesenswert?

Machs mit Linux, das Skript-Schreiben dauert max. eine Minute in Python 
oder Bash.

von Marc Horby (Gast)


Lesenswert?

Kann man nicht prüfen ob die Quellgröße identisch Zielgröße ist und dann 
triggern?

von Daniel A. (daniel-a)


Lesenswert?

Ich würde für sowas ein fuse dateisystem bauen. Bei windows nimmt man 
dann halt dokan_fuse. Erinnert sich eigentlich noch jemand an die 
Windows Aktenkofferordner? Die waren echt praktisch.

von Marco G. (grmg2010)


Lesenswert?

Marc Horby schrieb:
> Kann man nicht prüfen ob die Quellgröße identisch Zielgröße ist und dann
> triggern?

So war auch mein erster Ansatz, solange dich die Dateigröße ändert, wird 
die Datei noch kopiert. Leider kann ich nur die komplette Dateilänge 
auslesen, nicht die gerade schon vorhandene (Da Windows den Speicher 
bereits reserviert.)

Mr. Big schrieb:
> Machs mit Linux, das Skript-Schreiben dauert max. eine Minute in Python
> oder Bash.

Scheinbar schein für einige Linux immer die Lösung für alles zu sein.
Da das Programm später noch andere Funktionen enthalten soll, und ich 
bereits in VB.NET begonnen habe, würde ich gerne dabei bleiben
Außerdem Phyton läuft auch auf Windows, wenn ich mich nicht ganz irre. 
Könnte man nicht auch hier das Skript erstellen?

von Carl D. (jcw2)


Lesenswert?

Marco G. schrieb:
> Mr. Big schrieb:
>> Machs mit Linux, das Skript-Schreiben dauert max. eine Minute in Python
>> oder Bash.
>
> Scheinbar schein für einige Linux immer die Lösung für alles zu sein.
> Da das Programm später noch andere Funktionen enthalten soll, und ich
> bereits in VB.NET begonnen habe, würde ich gerne dabei bleiben
> Außerdem Phyton läuft auch auf Windows, wenn ich mich nicht ganz irre.
> Könnte man nicht auch hier das Skript erstellen?

nicht "mach's mit Linux, weil's das cooler ist"
sondern "mach's mit Linux, weil's beim Download Dateien anders 
behandelt"
(Datei hat solange Länge Null, bis alles in Schattendatei geladen wurde, 
dann werden "Namen getauscht)

BTW, das hab ich vor schon zu NT4.0-Zeiten gemacht, um Daten von Geräten 
im Versand (Waagen) zeitnah an ERP-Systeme zu schicken (und in max. 3s 
die ausgedrückte Rechnung zu haben). Ging damals in C++ (COM) und VB6. 
Wobei, WIMRE der "Download" nur ms gedauert hat, das Problem "alles da?" 
also nicht auftrat.

: Bearbeitet durch User
von Marco G. (grmg2010)


Lesenswert?

Carl D. schrieb:
> mach's mit Linux, weil's beim Download Dateien anders
> behandelt"

Nur beim Download, oder auch bei normalen Dateitransfers innerhalb des 
Dateisystems? Wird eine temporäredatei erzeugt?

Downloads behandelt Windows genauso, es wird eine temporäre Datei 
erzeugt, die in ihrer Größe wächst, erst wenn der Vorgang beendet wurde, 
wird die "richtige" Datei angelegt.

Da ich aber auf Windows festgelegt bin, bringen mir Tipps es mit Linux 
umzusetzen leider nicht weiter im Moment.

Bei kleinen Dateien ist es auch kein Problem, die werden schneller 
weggeschrieben als das Programm prüft. Es geht hier primär um große 
Dateien, die eine weile zum Kopieren benötigen.

von S. R. (svenska)


Lesenswert?

Marco G. schrieb:
> Downloads behandelt Windows genauso,

Nein: Aktuelle Browser behandeln Downloads so - Windows an sich nicht.

Und das gilt genau so auch für Linux - wget lädt standardmäßig in die 
Zieldatei, nicht in eine temporäre Datei.

von Arc N. (arc)


Lesenswert?

@Linux: Damit löst sich das Grundproblem genauso wenig. Je nach 
Dateisystem wird's da auch schon für in Dateien schreibenden Prozesse 
unmöglich zu erkennen, ob der Schreibvorgang tatsächlich abgeschlossen 
ist. U.a. z.B. btrfs 1)
Was beim Problem des TO unter Windows/NTFS alles zu beachten ist bspw. 
Raymond Chen 
https://blogs.msdn.microsoft.com/oldnewthing/20111226-00/?p=8813

1) btrfs https://btrfs.wiki.kernel.org/index.php/FAQ "Btrfs does not 
force all dirty data to disk on every fsync or O_SYNC operation, fsync 
is designed to be fast."

von Lomar (Gast)


Lesenswert?

Die anlegende Applikation muß nach Fertigstellung die Datei moven. Ich 
kann allerdings nicht sagen ob Windows die Filesystemsemantik 
(link/unlink) so regelt wie Unix.

von Lomar (Gast)


Lesenswert?

Arc N. schrieb:
> 1) btrfs https://btrfs.wiki.kernel.org/index.php/FAQ "Btrfs does not
> force all dirty data to disk on every fsync or O_SYNC operation, fsync
> is designed to be fast."

Alle Prozesse nutzen aber den selben Cache.

von N2 (Gast)


Lesenswert?

Hi,

Woher kommt denn die URL des Downloads ?

Eine Batch-Datei und wget tun es vielleicht auch ?
Da ich nicht darin fit bin eher Pseudo-Code:

set temp={von %1 nur den Dateinamen}
wget %1 -o /tmp/%1
copy /tmp/%1 /wohin/auch/immer/%1


Dann die URL per D&D draufziehen.


Gruß N2

von N2 (Gast)


Lesenswert?

An den richtigen drei Stellen bitte %1 durch %TEMP% ersetzen...

Gruß

von c-hater (Gast)


Lesenswert?

georg schrieb:

> ich habe es
> nur gewagt dir in einem technischen Punkt zu widersprechen. Für dich ist
> das wohl Insubordination

Nö, jeder darf natürlich seine eigene Meinung haben. Nur leider gibt es 
zu technischen Sachverhalten halt nicht wirklich Meinungen, sondern nur 
harte Fakten.

Und wenn dann irgensoein unwissender Blindflansch sich auf den Schlips 
getreten fühlt, weil seine feste Meinung halt nicht wirklich durch 
Fakten gedeckt ist: mir doch egal...

Ich will nur das Recht auf freie Meinungsäußerung hochhalten. Das 
schließt inbesondere ein: Wenn durch Fakten bewiesen ist, das eine 
Meinung geistiger Dünschiß ist, dann sollte man die entsprechende 
Aussage auch als geistigen Dünnschiß bezeichnen dürfen (oder halt auch 
den Meinungsäußerer als Blindflansch).

Das ist dann nur eins: Gleiches Recht für Alle. Schließlich äußere auch 
ich dann nur meine Meinung. Klar könnte ich das auch mit weniger 
"Fäkalausdrücken" tun, aber wozu der Aufwand? Und vor allem: längst 
nicht jeder versteht Sarkasmus und Ironie und in diese Ausdrucksmittel 
müßte ich ja meine Meinung verpacken, wenn ich sie nicht direkt sagen 
darf.

Im konkreten Fall hatte ich ja allerdings diesen Aufwand sogar 
tatsächlich getrieben. Und der Erfolg war: der Blindflansch fühlt sich 
immer noch angepißt und die anderen Doofen werden nur unnötig 
verwirrt...

Also ganz offensichtlich: vollkommen nutzlose Verschwendung von 
Lebenszeit. Fäkalausdrücke versteht jeder. Damit ist viel einfacher 
auszudrücken, wer doof ist, und zwar so, dass es auch andere Doofe 
sicher verstehen können...

von Carl D. (jcw2)


Lesenswert?

Was jetzt freie Meinungsäußerung oder freie Faktenbehauptung?
Oder je nach Bedarf?

von c-hater (Gast)


Lesenswert?

Carl D. schrieb:

> Was jetzt freie Meinungsäußerung oder freie Faktenbehauptung?

Freie (leicht angepißte) Meinungsäußerung natürlich. Ich bin allerdings 
nur zu gern bereit, über Fakten zu diskutieren. Also die Frage: Kannst 
du irgendwelche Fakten beitragen, die mein Wissen über das konkrete 
Problem erweitern könnten?

Falls ja, bin ich nur zu gern bereit, selbige zu assimilieren. Denn: Ich 
halte mich natürlich nicht für unfehlbar, sondern bin jederzeit bereit, 
zuzugeben, dass ich irgendwas übersehen/falsch interpretiert/nicht 
gewusst habe. Spätestens dann, wenn mir denn irgendwer schlüssig 
beweist, dass sowas passiert ist...

Ja, ich bin schon Scheiße, voll auf beweisbare Fakten fixiert. Wenig 
sozial...

Aber als Programmierer wohl in genau der richtigen Rolle. Bits haben 
schließlich auch keinerlei soziale Ader.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

c-hater schrieb:
> Fäkalausdrücke versteht jeder.

Sie fallen halt auf den zurück, der sie verwendet.

Meinst Du, daß Dich in diesem Forum auch nur irgendjemand ernstnimmt? 
Verhältst Du Dich auch am Arbeitsplatz so? Muss ein komischer 
Arbeitsplatz sein, wenn Du den so behalten kannst ...

von Carl D. (jcw2)


Lesenswert?

c-hater schrieb:
>
> Ja, ich bin schon Scheiße, voll auf beweisbare Fakten fixiert. Wenig
> sozial...
>
> Aber als Programmierer wohl in genau der richtigen Rolle. Bits haben
> schließlich auch keinerlei soziale Ader.

Zum Glück hatte ich in den letzten 35 Jahren mit derartigen 
Programmierern keinen Kontakt. Mit einem solchen K...brocken würde ich 
keine Minute in einem Zimmer verbringen wollen.

BTW, "beweisbare Fakten" sind erst dann bewiesene, wenn man sie bewiesen 
hat. Bis dahin sind es unbewiesene Behauptungen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.