| |
VB.NET - Ein- und UmsteigerFileSystemWatcher.Created feuert zu früh. | | | Autor: Schudi | Datum: 23.09.15 16:38 |
| Hallo,
ich brauche mal wieder Eure Hilfe.
Ich möchte ein Verzeichnis auf das "Erscheinen" von *.csv" Dateien überprüfen. Sobald eine solche Datei neu angelegt wird, soll diese verarbeitet werden.
Created "feuert" allerdings zu früh - nämlich bereits wenn die Datei vom "anderen" System angelegt wird. In diesem Moment kann die Datei aber noch in Benutzung sein, da das erstellende Programm diese noch füllt/schreibt.
Wie kann ich handeln, dass die Datei erst "gemeldet" wird, wenn das erstellende Programm diese schließt bzw. dann, wenn die Datei frei ist?
Oder muss ich im erstellten Handler für das created-Ereignis einfach immer wieder prüfen ob die Datei "frei"ist bis das zutrift?
Frage B: Wie sieht es aus, wenn das erstellende System die Datei erst als *.tmp anlegt und dann nach *.csv umbenennt? Greift da Created auch?
Bin für jede Anregung offen und danke Euch schon mal für Eure Hilfe! | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: Manfred X | Datum: 23.09.15 21:44 |
| Hallo!
Der Filesystemwatcher generiert - wie der Name zum Ausdruck bringt -
Events zu Vorgängen im Dateisystem.
"Created" signalisiert, daß ein neuer Eintrag im Dateisystem erstellt worden ist.
Dateizugriffe/-freigaben durch Anwendungen werden nicht beachtet,
weil dadurch Einträge im Dateisystem nicht modifiziert werden.
Deine Idee, die Datei nach dem Füllen umzubenennen, könnte für Deinen
Zweck funktionieren (allerdings: Renamed-Überwachung).
Allerdings würde ich die Änderung des Dateinamens als Kennung nutzen, nicht
die Dateierweiterung (xxx_tmp.csv --- xxx.csv)
| |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: DotNetErbse | Datum: 26.09.15 07:37 |
| Hallo Schudi,
ich würde nach dem Event des FSW in einer do-Loop Schleife die Datei zum schreiben öffnen und den Fehler abfangen, solange, bis der Fehler nicht mehr auftritt. dann ist die Datei vom Fremdprogramm geschlossen... und Du kannst auf die Datei zugreifen.
btw... der FSW feuert nicht zu früh...
Mit freundlichen Gr??en
DotNetErbse
[Es hei?t Paket und nicht Packet, auch wenn Standard augenscheinlich von Standar(t)e kommt,hei?t es dennoch Standar(d)]
Beitrag wurde zuletzt am 26.09.15 um 07:38:37 editiert. | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: Schudi | Datum: 27.09.15 10:22 |
| Moin DotNetErbse,
in der Art hatte ich mir bereits geholfen, aber ich finde das Ergebnis nicht wirklich elegant...
Public Function CheckIfFileIsFree (ByVal Dateiname As String) As Boolean
Dim Datei_verfuegbar As Boolean
Dim fs As FileStream
fs = New FileStream(Dateiname, FileMode.Open, FileAccess.ReadWrite, _
FileShare.None)
Dim sr As StreamReader
Do
Datei_verfuegbar = True
Try
sr = New StreamReader(fs)
sr.close()
Catch ex As IOException
Datei_verfuegbar = False 'Datei gesperrt
Catch ex As Exception
msgbox(ex.Message, MsgBoxStyle.Exclamation) 'andere Fehler melden
End Try
Thread.Sleep(100) 'kurz warten
Loop Until Datei_verfuegbar = True
' Aufräumen
sr.dispose()
Return Datei_verfuegbar
End Function Für Feedback wäre ich dankbar und vielleicht ist der Code ja gar nicht so schlecht... | |
FileSystemWatcher-Beispiel | | | Autor: Manfred X | Datum: 28.09.15 06:31 |
| Hallo!
Probier' mal diese Variante ....
Es wird ein Thread gestartet (CreateAndFill), der eine Datei exclusiv
zum Schreiben öffnet.
Es werden einige Text-Zeilen in einer Verzögerungs-Schleife eingetragen.
Der Zeitpunkt der Beendigung dieses Thread wird in einem Label (lblEnd)
angezeigt.
Der entprechend eingerichtete Filesystemwatcher (fsw) meldet im Created-Event
den Zeitpunkt des Erstellens dieser Datei (lblCreated) und im Changed-Event
das Schließen der Datei (lblChanged).
Zusätzlich wird der geschriebene Datei-Inhalt in der Routine gelesen, die
im Changed-Handler delegiert wird (Notify_Changed), und in eine Textbox
(txtFile) eingetragen.
Hinweis:
Die Überwachung des Filesystemwatchers arbeitet in einem Hintergrundthread,
deshalb ist im Rahmen der Ereignisverarbeitung ggf. Invoke erforderlich (vgl. Code).
Windows.Forms.Form:
Public Class frmFileSystemWatcherDemo
Dim WithEvents fsw As New IO.FileSystemWatcher
'Controls
Dim lblcreated As New Label With _
{.Parent = Me, .Width = 300}
Dim lblchanged As New Label With _
{.Parent = Me, .Top = 30, .Width = 300}
Dim lblend As New Label With _
{.Parent = Me, .Top = 60, .Width = 300}
Dim txtFile As New TextBox With _
{.Parent = Me, .Top = 100, .Width = 300, .Height = 150, _
.Multiline = True}
Delegate Sub changetypedel(ByVal ct As IO.WatcherChangeTypes)
Dim Show_Text As New changetypedel(AddressOf Notify_changed)
Dim filepath As String = "C:\daten\fsw.csv" 'zu überwachendes File
Private Sub frmFileSystemWatcherDemo_Load(sender As System.Object, _
e As System.EventArgs) Handles MyBase.Load
'Sicher stellen, daß die Datei nicht vorhanden ist
IO.File.Delete(filepath)
'Einrichten des Filesystemwatchers
With fsw
.BeginInit()
.Filter = "*.csv"
.NotifyFilter = _
IO.NotifyFilters.FileName Or IO.NotifyFilters.Size
.Path = IO.Path.GetDirectoryName(filepath)
.EnableRaisingEvents = True
.EndInit()
End With
Me.Show()
'Thread zum Erstellen und Füllen der Datei
Dim t As New Threading.Thread _
(New Threading.ThreadStart(AddressOf CreateAndFill))
t.Start()
End Sub
'====================================================
'FSW-Eventverarbeitung
'====================================================
Private Sub Notify_created()
lblcreated.Text = "FSW erstellt: " & Now.ToString
End Sub
Private Sub fsw_Created(sender As Object, _
e As System.IO.FileSystemEventArgs) Handles fsw.Created
Me.Invoke(New MethodInvoker(AddressOf Notify_created))
End Sub
Private Sub Notify_changed(Changetype As IO.WatcherChangeTypes)
lblchanged.Text = _
"FSW geändert: " & Now.ToString & " " & Changetype.ToString
'Dateiinhalt nach dem Changed-Event lesen
txtFile.Text = IO.File.ReadAllText(filepath)
Me.Refresh()
End Sub
Private Sub fsw_Changed(sender As Object, _
e As System.IO.FileSystemEventArgs) Handles fsw.Changed
Me.Invoke(Show_Text, {e.ChangeType})
End Sub
'===================================================
'Thread zum Füllen der Datei
'===================================================
Private Sub Notify_ThreadEnd()
'CreateAndFill-Thread wird beendet
lblend.Text = "Thread beendet: " & Now.ToString
End Sub
Private Sub CreateAndFill()
'Filestream exclusiv öffnen
Using fs As New IO.FileStream(filepath, IO.FileMode.CreateNew, _
IO.FileAccess.Write, IO.FileShare.None), _
bw As New IO.BinaryWriter(fs)
For i As Integer = 0 To 10
bw.Write("Zeile " & CStr(i) & ";" & Now.ToString & vbCrLf)
Threading.Thread.Sleep(1000) 'Verzögerung
Next i
'End Using schließt den Filestream / Dateifreigabe
End Using
'Zeitpunkt der Dateifreigabe anzeigen
Me.Invoke(New MethodInvoker(AddressOf Notify_ThreadEnd))
End Sub
End Class
Beitrag wurde zuletzt am 28.09.15 um 06:33:02 editiert. | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: svss | Datum: 07.10.15 17:42 |
| Hier die Funktion
''' <summary>
''' Prueft ob die Datei noch im Zugriff ist
''' </summary>
''' <param name="fileName"></param>
''' <returns></returns>
''' <remarks></remarks>
Private Function IsFileOpen(ByVal fileName As String) As Boolean
Try
If File.Exists(fileName) Then
Dim stream As FileStream = File.Open(fileName, FileMode.Open, _
FileAccess.Read, FileShare.None)
stream.Dispose()
End If
Return False
Catch ex As IOException
ex = Nothing
Return True
End Try
End Function Und hier der Aufruf im CHANGED Event
While IsFileOpen(e.FullPath) = True
Threading.Thread.Sleep(100)
End While | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: DotNetErbse | Datum: 08.10.15 11:55 |
| Hallo,
sollte man den Stream nicht zum Schreiben öffnen?
Mit freundlichen Gr??en
DotNetErbse
[Es hei?t Paket und nicht Packet, auch wenn Standard augenscheinlich von Standar(t)e kommt,hei?t es dennoch Standar(d)] | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: JangoF | Datum: 08.10.15 13:00 |
| Das FileShare.None dürfte dafür sorgen das man es nur öffnen kann wenn kein anderer es geöffnet hat. | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: svss | Datum: 09.10.15 10:46 |
| exakt ! | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: DotNetErbse | Datum: 12.10.15 15:50 |
| ja, und das war die Anforderung... er kann das Event nicht benutzen, weil die erstellende Anwendung noch auf die Datei schreibt.
Mit freundlichen Gr??en
DotNetErbse
[Es hei?t Paket und nicht Packet, auch wenn Standard augenscheinlich von Standar(t)e kommt,hei?t es dennoch Standar(d)] | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: svss | Datum: 15.10.15 19:25 |
| ...und nach dem
While IsFileOpen(e.FullPath) = True
Threading.Thread.Sleep(100)
End While Schreibt er den Code den er braucht | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: JangoF | Datum: 16.10.15 10:44 |
| Einen Zähler der das ganze nach einer festgelegten Anzahl von versuchen abbricht ist auch sinnvoll.
Ansonsten kann, wenn aus irgendeinem Grund nie zugriff gewährt wird, das in eine Endlosschleife geraden. | |
Re: FileSystemWatcher.Created feuert zu früh. | | | Autor: svss | Datum: 19.10.15 16:34 |
| Ein solcher Zähler wäre Unfug.
Die Schleife läuft solange, solange die Datei von einem anderen User/Anwendung/... im Zugriff ist.
Ist Sie endlos - hat der anderen User/Anwendung/... die Datei eben nicht freigegeben und ich kann Sie auch nicht bearbeiten.
| |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
vb@rchiv CD Vol.6 vb@rchiv Vol.6
Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
Online-Update-Funktion Entwickler-Vollversionen u.v.m.Jetzt zugreifen Tipp des Monats TOP! Unser Nr. 1
Neu! sevDataGrid 3.0
Mehrspaltige Listen, mit oder ohne DB-Anbindung. Autom. Sortierung, Editieren von Spalteninhalten oder das interaktive Hinzufügen von Datenzeilen sind ebenso möglich wie das Erstellen eines Web-Reports. Weitere Infos
|