none
Dateien gelockt öffnen RRS feed

  • Frage

  • Hallo,

    welche Mechanismen eignen sich für folgende Anforderung.

    Netzwerk.

       Mehrere Applikationen greifen auf eine Datei zu.

          Öffnet man eine Datei, sollte eine weitere temporäre Datei   .TEMP geöffnet werden, um visuell zu sehen, dass diese geöffnet ist.

    Nice to have

        Anstatt .temp    

    •                 .temp-ComputerName-IP
    •                 .temp-ComputerName-Fertigungslinie

    Somit sieht jeder, wer die Datei momentan bearbeitet.

    Wer kann mir Tipps und Beispielcode geben?

    Ähnlich macht es ja Excel, wenn mehrere Anwender auf dieselbe Datei zugreifen.

    Viele Grüße Sandra

    • Typ geändert Stefan FalzModerator Montag, 26. September 2016 09:24 Eher eine Frage als eine Diskussion
    Montag, 26. September 2016 08:01

Antworten

  • Hi,

    der Code von Thomas prüft sehr schön, ob die Datei geöffnet werden kann. Aber die Idee von mir wäre ja, dass die Datei ständig geöffnet bleiben würde. Also die eigentliche Datei wird so wie von Thomas angegeben, geöffnet und eben bis zum Programmende nicht wieder geschlossen.

    nachdem die eigentliche Datei exklusiv geöffnet wurde, würde ich die andere Beschreibungsdatei einfach erstellen und direkt wieder schließen. Es macht keinen Sinn mehrere Dateien geöffnet zu halten.

    Vor dem schließen der Haupt-Datei kann die Applikation die temp Datei lesen (um zu sehen, ob es die eigene Datei ist) und dann ggf. löschen.

    Die ganzen Mechanismen bezüglich Cleanup sollten dann schon vom System kommen. Kann man ja gerne einmal austesten:
    - Lösung schreiben
    - Applikation starten - die Datei sollte gelockt sein. (Testen!)
    - Rechner ausschalten - die Datei wurde nicht aktiv entsperrt - Prüfen, ob Du auf die Datei zugreifen kannst. Evtl. nach einem Timeout erneut probieren.
    - Evtl. noch ein Test, wenn man einen Rechner vom Netz trennt, wenn die Applikation läuft. Hier erwarte ich ein ähnliches Verhalten wie beim Ausschalten.

    Das Entsperren bei einem Applikations-Absturz ist sicher gestellt, da Windows dann die Ressourcen der Applikation eh schliesst / freigibt. Aber auch das kann man testen durch ein kill der Applikation.

    Das Verhalten, das bei den Tests protokolliert wurde, muss dann noch bewertet werden. Ist das ok oder ist das nicht ok? Wenn es nicht ok ist: Was müsste anders sein?

    Viele Grüße,

    Konrad

    Donnerstag, 29. September 2016 10:28
  • Hallo Sandra,

    andere Antwortende und ich auch hatten schon geschrieben, dass es kein Standvorgehen hierbei gibt und Du um eine Eigenentwicklung wohl nicht drumrum kommst.

    Wie das aussehen kann, haben wir dir auch schon beschrieben.

    Vor dem Öffnen einer Datei prüfst Du, ob es eine dazu passende Tempdatei gibt. Falls ja, lies diese aus und zeig die Meldung an.

    Das geht bspw. über File.Exists( ... ). Den Namen der Tempdatei solltest Du selbst wählen und diesen so vergeben, dass man am Namen schon sehen kann, für welche Datei sie "zuständig" ist. Den Inhalt kannst Du beliebig aufbauen, wenn Du überhaupt Inhalt drin haben willst. Bspw. könnte dort der Username und der PC Name des Benutzers stehen, der die Datei bearbeitet. Andere Prozesse können diese Tempdatei lesen und dann ihrem Benutzer anzeigen, wer die eigentliche Datei grade bearbeitet.

    Falls keine Tempdatei existiert, öffne die Originaldatei exklusiv, erzeuge die Tempdatei mit Nur Lese Rechten für andere Prozesse und arbeite einfach deinen Code ab.

    Das exklusive Öffnen kann man über File.Open( ... ) mit den entsprechenden Parametern für die Sperren erledigen. Die Tempdatei kann über dieselbe Methode erzeugt werden, lediglich beim letzten Parameter für die Zugriffsart dann nicht None, sondern Read angeben, damit die Datei von den anderen Prozessen gelesen werden kann.

    Wenn fertig, Originaldatei speichern und schließen, Tempdatei löschen.

    Speichern und schließen sollte dir bekannt sein, File.Delete( ... ) zum Löschen der Tempdatei ja auch.

    Was genau ist denn nun dein Problem?

    P.S.: Ggfs. solltest Du noch einen FileWatcher mit integrieren, der den Benutzer dann automatisch benachrichtigen kann, wenn die Originaldatei wieder bearbeitbar ist (bspw. indem der FileWatcher auf das Lösch Event der Temp Datei reagiert und dann probiert, die Originaldatei exklusiv zu öffnen)

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Mittwoch, 5. Oktober 2016 17:27
    Moderator
  • Hallo Sandra,

    manchmal ist es einfach besser mit dem programmieren anzufangen ohne eine kompletten Plan zu haben.

    Wie Konrad schon geschrieben hat, solltest Du zunächst herausfinden ob man die Datei im Netzwerk sperren kann.

    Ohne diese Info ist alles nur Theorie und jede weitere Planung sinnlos.

    So könnte die Prüfung aussehen:

    void LockPruefung()
            {
                string netzwerkPath = "z:\\Freigabe\\";
                string fileName = "Test.txt";
                string filePath = System.IO.Path.Combine(netzwerkPath, fileName);
    
                if (!File.Exists(filePath))
                {
                    System.IO.File.WriteAllText(filePath, "Mal ein test");
                }
    
                var tFile = System.IO.File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    
    
                if (IsFileLocked(new FileInfo(filePath)))
                {
                    //Alles gut, wenig arbeit
                }
                else
                {
                    //ausgezeichnet eine Herausforderung
                }
    
            }
    
            protected virtual bool IsFileLocked(FileInfo file)
            {
                FileStream stream = null;
    
                try
                {
                    stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                }
                catch (IOException)
                {
                    //the file is unavailable because it is:
                    //still being written to
                    //or being processed by another thread
                    //or does not exist (has already been processed)
                    return true;
                }
                finally
                {
                    if (stream != null)
                        stream.Close();
                }
    
                //file is not locked
                return false;
            }

    Gruß

    Thomas


    Icon für UWP: https://www.microsoft.com/store/apps/9nblggh5fzpm




    Mittwoch, 5. Oktober 2016 23:01

Alle Antworten

  • Hi Sandra,

    als erstes würde ich schauen, in wie weit das Netzwerk das blockierende Öffnen von Dateien erlaubt. Dies sollte eigentlich immer der Fall sein und genau das würde alles deutlich vereinfachen.

    Die File.Open Methode ermöglichst Dir dann, die Datei genau so zu öffnen, wie Du dies benötigst, also z.B. mittels FileShare.None (das wäre exclusive Nutzung und Andere können die Datei dann auch nicht Lesen).

    Wenn dies technisch funktioniert (müsstest Du einmal prüfen), dann kannst Du natürlich immer noch andere Dateien erzeugen, damit die Nutzung deutlich wird. So eine Datei könnte dann auch exklusive geöffnet sein und z.B. für Schreib-/Lesetests verwendet werden).

    Das Vorgehen ist dann halt, dass Du die Datei dann einfach exklusiv öffnest und dann geöffnet hältst bis Du fertig bist (Also die Datei nicht vorher löschen).

    Damit hast Du schon eine recht große Sicherheit, also z.B. ein Recovery, wenn Dein System ausfällt oder der Server ausfällt und dann wieder hoch kommt. (Dann ist so eine .Temp Datei ja evtl. noch da!).

    Bezüglich der .Temp Datei - hier würde ich keine weiteren Infos in den Dateinamen packen. Diese Datei kann ja mit FileShare.Read geöffnet sein so dass die Informationen einfach in die Datei geschrieben werden. Jeder, der will, kann sich dann die Datei ansehen und die Informationen dann lesen.

    Wie oben erwähnt: Falls Du so Dateien länger offen halten möchtest, so würde ich bei einem Netzwerk-Share evtl. etwas vorsichtiger sein und von Zeit zu Zeit auch Operationen (z.B. auf dem Temp File) ausführen. Damit kannst Du Probleme mit dem Share aufspüren - so es kritisch ist. Bei Unkritischen Dingen wie z.B. die Office Dateien, wäre es relativ unkritisch - da kann man dann einfach hin gehen und eine Art "Save As" Dialog einbauen, wenn ein speichern schief gehen sollte.

    Mit den besten Grüßen,

    Konrad

    Montag, 26. September 2016 10:08
  • Das Vorgehen ist dann halt, dass Du die Datei dann einfach exklusiv öffnest und dann geöffnet hältst bis Du fertig bist (Also die Datei nicht vorher löschen).

    Hallo Konrad,

    Danke für die Antwort.

    Mein Problem, wie erzeuge ich die .Temp Datei?

     

    Also PC1 --> Zugriff auf xxxx.XML

                         Schreibe xxxx.Temp mit Computername etc.

         PC2 --> Zugriff auf xxxx.XML

                      Jetzt soll eine Info kommen, bereits geöffnet von PC Computername

                 Zum Lesen darf ich die öffnen, halt nicht mehr schreiben.

    Hast Du, kennst Du eine Beispielapplikation, wie man das korrekt angeht.

     

    Es kann immer nur 1 PC die Datei bearbeiten, ändern, speichern.

    Gibt es Mechanismen, die bei einem Absturz, die Datei dennoch lesen kann.

      Oder anders gefragt, wer könnte dann die TEMP Datei löschen?

     

    Viele Grüße Sandra


    Dienstag, 27. September 2016 16:19
  • Hallo Sandra,

    eine Standardvorgehensweise gibt es dafür nicht, das musst Du also schon selbst programmieren.

    Vor dem Öffnen einer Datei prüfst Du, ob es eine dazu passende Tempdatei gibt. Falls ja, lies diese aus und zeig die Meldung an.

    Falls keine Tempdatei existiert, öffne die Originaldatei exklusiv, erzeuge die Tempdatei mit Nur Lese Rechten für andere Prozesse und arbeite einfach deinen Code ab.

    Wenn fertig, Originaldatei speichern und schließen, Tempdatei löschen.

    Die einzelnen Mechanismen kennst Du ja alle, daher sollte das doch kein Problem sein, oder?


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 27. September 2016 16:33
    Moderator
  • Hallo,

    wie die anderen schon schreiben wirst Du keinen Standard Weg finden.

    Ich habe so etwas für DropBox entwickelt. Du musst dich mit der Frage auseinander setzten was passiert wenn der Rechner der die Temp erzeugt hat abstürzt und die Temp selbst nicht mehr löschen kann/wird. Bei welchem Szenario darf einen andere Rechner die Datei wieder Freigeben.

    Wenn Du das geklärt hast sollte alles andere kein Problem sein.

    Solltest Du die Datei wirklich locken können und mit einem Snippet wie dem nachfolgenden überprüfen können ob sie offen ist. Sollte das alles kein Problem sein. Dann kannst Du einfach immer versuchen die Datei zu öffnen, sollte die gelockt sein die Temp auslesen und dem User eine Meldung anzeigen das sie von User xy bearbeitet wird.

    protected virtual bool IsFileLocked(FileInfo file)
            {
                FileStream stream = null;
    
                try
                {
                    stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                }
                catch (IOException)
                {
                    //the file is unavailable because it is:
                    //still being written to
                    //or being processed by another thread
                    //or does not exist (has already been processed)
                    return true;
                }
                finally
                {
                    if (stream != null)
                        stream.Close();
                }
    
                //file is not locked
                return false;
            }

    Sollte das nicht der Fall sein musst Du dir einen anderen Mechanismus überlegen.

    Gruß

    Thomas


    Icon für UWP: https://www.microsoft.com/store/apps/9nblggh5fzpm


    Dienstag, 27. September 2016 21:50
  • Hi,

    der Code von Thomas prüft sehr schön, ob die Datei geöffnet werden kann. Aber die Idee von mir wäre ja, dass die Datei ständig geöffnet bleiben würde. Also die eigentliche Datei wird so wie von Thomas angegeben, geöffnet und eben bis zum Programmende nicht wieder geschlossen.

    nachdem die eigentliche Datei exklusiv geöffnet wurde, würde ich die andere Beschreibungsdatei einfach erstellen und direkt wieder schließen. Es macht keinen Sinn mehrere Dateien geöffnet zu halten.

    Vor dem schließen der Haupt-Datei kann die Applikation die temp Datei lesen (um zu sehen, ob es die eigene Datei ist) und dann ggf. löschen.

    Die ganzen Mechanismen bezüglich Cleanup sollten dann schon vom System kommen. Kann man ja gerne einmal austesten:
    - Lösung schreiben
    - Applikation starten - die Datei sollte gelockt sein. (Testen!)
    - Rechner ausschalten - die Datei wurde nicht aktiv entsperrt - Prüfen, ob Du auf die Datei zugreifen kannst. Evtl. nach einem Timeout erneut probieren.
    - Evtl. noch ein Test, wenn man einen Rechner vom Netz trennt, wenn die Applikation läuft. Hier erwarte ich ein ähnliches Verhalten wie beim Ausschalten.

    Das Entsperren bei einem Applikations-Absturz ist sicher gestellt, da Windows dann die Ressourcen der Applikation eh schliesst / freigibt. Aber auch das kann man testen durch ein kill der Applikation.

    Das Verhalten, das bei den Tests protokolliert wurde, muss dann noch bewertet werden. Ist das ok oder ist das nicht ok? Wenn es nicht ok ist: Was müsste anders sein?

    Viele Grüße,

    Konrad

    Donnerstag, 29. September 2016 10:28
  • Hallo Konrad,

    Danke mal.

    Interessehalber wie handelt das Word und Excel.

    Microsoft macht es irgendwie mit $ Temp etc.

    Weißt Du es?

    Grüße Sandra

    Dienstag, 4. Oktober 2016 16:52
  • Hallo Sandra,

    auch interessehalber: Warum willst Du das wissen? Probier doch erst mal die Sachen, die dir die Antwortenden hier geschrieben haben. Darauf gehst Du leider wieder mit keinem Wort ein.

    Wenn es dir zu kompliziert ist, lass es dir halt von jemandem schreiben, es findet sich bestimmt jemand, der das für dich macht.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 4. Oktober 2016 17:06
    Moderator
  • Wenn es dir zu kompliziert ist, lass es dir halt von jemandem schreiben, es findet sich bestimmt jemand, der das für dich macht.



    Hallo Stefan,

    ja ok, die konkrete Vorgehensweise, sprich Coding ist mir nicht ganz klar.
    Die erste App öffnet die Datei, schreibt also die .Temp
    Alle anderen Apps können die Datei einlesen, aber eben nicht speichern.
    Wenn diese auf 'Speichern' klicken sollte ein Hinweis erscheinen, mit Infos aus der Temp Datei.
          Wer sperrt diese, wer arbeitet daran?
    Wenn Du eine kleine Beispielapp hast, zur Verfügung stellen kannst, bedanke ich mich.
    Ich dachte einfach, es gibt so eine Art Richtlinie, Vorgehensweise, wie man diese Anforderung behandelt.
    Man muss ja nicht alles neu erfinden.
      
    Viele Grüße Sandra

    Mittwoch, 5. Oktober 2016 17:10
  • Hallo Sandra,

    andere Antwortende und ich auch hatten schon geschrieben, dass es kein Standvorgehen hierbei gibt und Du um eine Eigenentwicklung wohl nicht drumrum kommst.

    Wie das aussehen kann, haben wir dir auch schon beschrieben.

    Vor dem Öffnen einer Datei prüfst Du, ob es eine dazu passende Tempdatei gibt. Falls ja, lies diese aus und zeig die Meldung an.

    Das geht bspw. über File.Exists( ... ). Den Namen der Tempdatei solltest Du selbst wählen und diesen so vergeben, dass man am Namen schon sehen kann, für welche Datei sie "zuständig" ist. Den Inhalt kannst Du beliebig aufbauen, wenn Du überhaupt Inhalt drin haben willst. Bspw. könnte dort der Username und der PC Name des Benutzers stehen, der die Datei bearbeitet. Andere Prozesse können diese Tempdatei lesen und dann ihrem Benutzer anzeigen, wer die eigentliche Datei grade bearbeitet.

    Falls keine Tempdatei existiert, öffne die Originaldatei exklusiv, erzeuge die Tempdatei mit Nur Lese Rechten für andere Prozesse und arbeite einfach deinen Code ab.

    Das exklusive Öffnen kann man über File.Open( ... ) mit den entsprechenden Parametern für die Sperren erledigen. Die Tempdatei kann über dieselbe Methode erzeugt werden, lediglich beim letzten Parameter für die Zugriffsart dann nicht None, sondern Read angeben, damit die Datei von den anderen Prozessen gelesen werden kann.

    Wenn fertig, Originaldatei speichern und schließen, Tempdatei löschen.

    Speichern und schließen sollte dir bekannt sein, File.Delete( ... ) zum Löschen der Tempdatei ja auch.

    Was genau ist denn nun dein Problem?

    P.S.: Ggfs. solltest Du noch einen FileWatcher mit integrieren, der den Benutzer dann automatisch benachrichtigen kann, wenn die Originaldatei wieder bearbeitbar ist (bspw. indem der FileWatcher auf das Lösch Event der Temp Datei reagiert und dann probiert, die Originaldatei exklusiv zu öffnen)

     


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community


    Mittwoch, 5. Oktober 2016 17:27
    Moderator
  • Hallo Sandra,

    manchmal ist es einfach besser mit dem programmieren anzufangen ohne eine kompletten Plan zu haben.

    Wie Konrad schon geschrieben hat, solltest Du zunächst herausfinden ob man die Datei im Netzwerk sperren kann.

    Ohne diese Info ist alles nur Theorie und jede weitere Planung sinnlos.

    So könnte die Prüfung aussehen:

    void LockPruefung()
            {
                string netzwerkPath = "z:\\Freigabe\\";
                string fileName = "Test.txt";
                string filePath = System.IO.Path.Combine(netzwerkPath, fileName);
    
                if (!File.Exists(filePath))
                {
                    System.IO.File.WriteAllText(filePath, "Mal ein test");
                }
    
                var tFile = System.IO.File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
    
    
                if (IsFileLocked(new FileInfo(filePath)))
                {
                    //Alles gut, wenig arbeit
                }
                else
                {
                    //ausgezeichnet eine Herausforderung
                }
    
            }
    
            protected virtual bool IsFileLocked(FileInfo file)
            {
                FileStream stream = null;
    
                try
                {
                    stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
                }
                catch (IOException)
                {
                    //the file is unavailable because it is:
                    //still being written to
                    //or being processed by another thread
                    //or does not exist (has already been processed)
                    return true;
                }
                finally
                {
                    if (stream != null)
                        stream.Close();
                }
    
                //file is not locked
                return false;
            }

    Gruß

    Thomas


    Icon für UWP: https://www.microsoft.com/store/apps/9nblggh5fzpm




    Mittwoch, 5. Oktober 2016 23:01
  • Was genau ist denn nun dein Problem?


    Hallo Zusammen,

    Danke an Alle!

    Ich schaue, dass ich mit den Infos zurecht komme.

    Viele Grüße Sandra

    Donnerstag, 6. Oktober 2016 17:09