2009-07-07 10 views
5

Ich möchte eine Datei erstellen und öffnen, aber nur, wenn sie nicht existiert. Ich möchte nicht eine Datei verwenden. Existiert, weil ein Thread nach dem Erstellen einer Datei mit dem gleichen Namen wechseln.Wie erkennen System.IO.IOException Ursache von vorhandenen Datei?

Wie überprüfe ich, ob die Ausnahme System.IO.IOException von der vorhandenen Datei verursacht wurde? Ich bevorzuge es, den Fehler msg nicht zu analysieren (auch wenn es so einfach sein kann wie .indexOf ("exist"))

Wie soll ich das machen?

+0

die Datei eine Semaphore, warum so viel Streit? – DevelopingChris

+0

DevelopingChris: Nein, ich möchte es nicht versehentlich überschreiben, da es eine Chance gibt, dass mein Zufallsgenerator (Zufallsgenerator) aufgrund von Multicores und Synchronisation dieselben IDs erzeugt. –

+0

Siehe auch http://StackOverflow.com/questions/425956/ How-Do-I-Ermitteln-wenn-eine-Ausnahme-ist-geworfen-wegen-einer-Freigabe-Verletzung. Die angenommene Antwort hat einen sehr nützlichen Link. – finnw

Antwort

5

Sie sollten es vermeiden, logische Entscheidungen basierend auf dem Inhalt der Exception.Message-Eigenschaft zu treffen. Das ist definiert als eine von Menschen lesbare Nachricht, nicht etwas, was ein Programm lesen kann. Solche Nachrichten können ohne vorherige Ankündigung geändert werden.

Von Menschen lesbare Nachrichten ändern sich oft, um sie für Menschen lesbarer zu machen. Das wird dein Programm nicht glücklicher machen.


Wie Sie das Problem der Programmlogik zu sagen, vielleicht in der Lage, in Abhängigkeit von den Menschen lesbaren Nachrichten ist ein Haustier ärgern von mir - ich werde Sie nicht wie lange sagen, denn das ist mir alt fühlen würde . Das hat mich von etwas abgelenkt, das offensichtlich sein sollte.

Überprüfen Sie, ob Sie eine System.IO.FileNotFoundException erhalten, wenn die Datei nicht existiert. Versuchen Sie, das anstelle von IOException zu erfassen.

+0

das ist genau das Problem. Ich habe keine Ahnung, wie ich es überprüfen soll. Ich denke, ich könnte .exist verwenden, aber das fühlt sich schlampig an. –

+0

Sie haben meinen Standpunkt verfehlt. Überprüfen Sie nie die Nachrichteneigenschaft. –

+0

Während ich der Stimmung zustimme, kann ich an Ausnahmen denken (kein Wortspiel beabsichtigt). –

0

Sie können File.Open verwenden und es mit FileMode.OpenOrCreate aufrufen.

Pro Kommentar: Okay, wie wäre es mit FileMode.CreateNew? Wenn es bereits eine gibt, erhalten Sie eine IOException, andernfalls erstellen Sie eine neue.

+1

Das ist genau das, was acidzombie24 nicht will ... –

+0

Oh ich verstehe, du meinst, er will es nicht öffnen, wenn es schon da ist? –

+0

Er sagte, er wolle "eine Datei erstellen und öffnen, aber nur, wenn sie nicht existiert". Genau das macht CreateNew. Ich habe +1 gegeben, um die unfairen -1 zu kompensieren. –

3

Sie könnten File.Exists() ... immer aus dem Ausnahme-Catch-Block heraus überprüfen. Sie wollen vorher nicht nach Threading suchen - überprüfen Sie, nachdem Sie bereits wissen, dass Sie ein Problem haben.

Angenommen, Sie löschen die Datei nicht plötzlich aus einem anderen Thread, dies wäre eine einfache und offensichtliche Möglichkeit, dies zu tun.

Vergessen Sie nicht, dass die Datei.Exists selbst eine Ausnahme verursachen kann, also stellen Sie sicher, dass Sie sie erneut abfangen.

+2

Gibt es dort keine Race Condition? –

+0

sollte es nicht mit der Situation sein, die er beschrieben hat, aber das ist, was ich mit meinem zweiten Absatz angedeutet habe. es könnte eine einfache Lösung für sein Problem sein, obwohl –

+0

auch in Betracht ziehen muss, wie viel Prozent der Zeit er erwartet, dass die Datei dort sein –

6

Ich bin mir nicht sicher, ob er die Datei überhaupt öffnen möchte, wenn sie bereits existiert.

Ich denke, er ist eigentlich nach FileMode.CreateNew wird dies eine IOException werfen, wenn die Datei bereits existiert, aber sonst wird es erstellen und öffnen.

+1

, aber er machte sich Sorgen wegen anderer Gründe für die Ausnahme - wie 'Erlaubnis verweigert' usw. Der Kern der Frage bestand darin, zwischen verschiedenen möglichen Gründen zu unterscheiden für eine Ausnahme. –

+0

Die Dokumentation zum 'FileStream'-Konstruktor deutet sehr stark darauf hin, dass bei diesem Modus' IOException' nur dann ausgelöst wird, wenn die Datei bereits existiert, andernfalls erhalten Sie eine der abgeleiteten (und spezifischeren Ausnahmen). Sie haben also recht, dass der Exception-Handler prüfen muss, ob der eigentliche Ausnahme-Typ "IOException" ist (oder nicht). – jerryjvl

3

Ihre beste Option ist hier, die CreateNew Option zu verwenden, wenn Sie die Datei zum Schreiben öffnen.

Es gibt keine einfache Möglichkeit, die Existenz einer Datei auf der Festplatte zu überprüfen. Das einzige, was Sie überprüfen können, ist, ob eine Datei verwendet wird oder nicht auf dem Datenträger vorhanden ist, auf den der Prozess mindestens eine eingeschränkte Form des Zugriffs hat.

Auch wenn Sie alle Zugriffe auf eine Datei von Ihrer Anwendung aus steuern, können Sie nicht zuverlässig verhindern, dass eine andere Anwendung die Datei erstellt/löscht. Selbst mit ausreichenden Sperren auf Dateisystemebene können Benutzer ruchlose Dinge tun, wie beispielsweise einen USB-Stick aus dem Computer nehmen.

Der beste Weg, um diese Art von Problem zu nähern, ist die Verwendung offener Optionen wie CreateNew.Dadurch kann die Operation nur erfolgreich ausgeführt werden, wenn die Datei zum Zeitpunkt der Erstellung nicht existiert. Sie können die Ausnahme zu diesem Zeitpunkt abfangen und versuchen, daraus abzuleiten, ob sie von der vorhandenen Datei oder einer anderen ungültigen Zugriffsausnahme stammt.

Methoden wie File.Exist ein falsches Gefühl der Sicherheit zu Ihrer Code-Basis geben und eng am Check-in überprüft werden sollte.