File.Exists - case sensitive

  • VB.NET

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von Peter329.

    File.Exists - case sensitive

    Hi,

    ich möchte abprüfen, ob ein File schon vorhanden ist. Dazu verwende ich die "File.Exists" Methode.

    Kaum zu glauben, aber diese Methode ist NICHT case sensitive! Wer es nicht glaubt, der kann das leicht ausprobieren:

    VB.NET-Quellcode

    1. If File.Exists("C:\test.txt") Then MsgBox("test.txt OK")
    2. If File.Exists("C:\Test.txt") Then MsgBox("Test.txt OK")
    3. If File.Exists("C:\TEST.TXT") Then MsgBox("TEST.TXT OK")

    Man erhält drei Mal OK, obwohl nur die Datei "test.txt" existiert.

    Fragt mich nicht warum, aber ich benötige die Abfrage "case sensitive", d.h. es darf nur ein "OK" ausgegeben werden.

    Geht das in VB?

    Natürlich könnte ich mir die FileListe ausgeben lassen und dann mit .Contains die Existenz abfragen! Aber das ist natürlich durchs Knie in die Brust geschossen! Gibt es eine bessere Möglichkeit?

    LG
    Peter

    Peter329 schrieb:

    aber diese Methode ist NICHT case sensitive
    unter Windows, korrekt.
    Unter Unix ist das case-sensitive.
    ----
    Damit wir beide dasselbe meinen: NICHT case sensitive heißt: die schreibweise ist egal. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Danke, erst mal für deinen Rat.

    Leider kann ich das nicht bestätigen.

    VB.NET-Quellcode

    1. Try
    2. Dim myStream As System.IO.FileStream = New System.IO.FileStream("C:\TEST.TXT", IO.FileMode.CreateNew)
    3. Catch ex As Exception
    4. MsgBox("Cannot create stream C:\TEST.TXT")
    5. End Try


    Die MsgBox wird angezeigt, obwohl die Datei TEST.TXT (in dieser Schreibweise) nicht existiert. Die Exception wird also geworfen und somit ist auch dieses Verfahren ist nicht case sensitive!

    @jvbsl .... warum ich das brauche erkläre ich dir, wenn ich das Problem gelöst habe. Lass uns erst mal auf die Problematik konzentrieren.

    @RFG jau ...

    case sensitive = Schreibweise wird berücksichtigt

    nicht case sensitive = Schreibweise ist egal

    Und ich hätte es gerne "case sensitive" .... :) alles klar?


    ouch .... jetzt verstehe ich das ... !

    Mit anderen Worten, die Dateien "C:\test.txt" und "C:\TEST.TXT" können nicht gemeinsam existieren! Das war mir nicht klar!

    Und damit ziehe ich meine Frage zurück.

    Für alle die es interessiert: Ich will Dateien per Programm Dialog umbenennen ... dazu frage ich ab, ob es die neue Datei schon gibt. Wenn sie bereits vorhanden ist, gebe ich eine Meldung aus und verlange einen anderen Namen.

    Das knallt aber, wenn ich die Datei test.txt in TEST.TXT umbenennen will! Das ist nämlich zulässig und darf nicht abgewiesen werden.

    Na, jetzt weiß ich endlich, wie ich die Logik meines Programms ändern muss! :)

    Herzlichen Dank an alle Ratgeber.

    LG
    Peter

    Peter329 schrieb:

    Die MsgBox wird angezeigt
    Gib mal bitte ex.Message aus, damit wir die genaue Ursache sehen.
    -----------------

    Peter329 schrieb:

    Wenn sie bereits vorhanden ist, gebe ich eine Meldung aus.
    Eine nicht vorhandene Datei kannst Du nicht umbenennen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Btw. kann auch Move dazu verwendet werden, das kann ebenfalls einen Fehler werfen.
    Im Allgemeinen ist es so, dass Dateioperationen, "atomar" sein sollten, solange sie auf nicht-gesperrten Dateien (Dateien, die sie geöffnet haben), operieren. D.h. Löschen und Schreiben wäre Create, Schreiben, sofern nicht vorhanden, wäre CreateNew, usw. In so einem Fall ist Try-Catch zulässig. Hintergrund ist der, dass es möglich ist, dass andere Programm die Datei zwischen Abfrage und Behandlung bereits verändern können.

    Gruß
    ~blaze~
    (Edit: inzwischen wurde Post #7 gepostet.)

    Du hast zwei Optionen:
    1. Ignorieren, dass Dateipfade case insensitive sind. Wie erwähnt wurde, kann es nicht gleichzeitig eine C:\TEST.txt und eine C:\test.txt geben. Es dürften auch sonst keine Probleme auftreten.
    Das Problem ist, dass wir nicht wissen, was Du machen willst (willst Du uns ja noch nicht sagen). Deshalb können wir nicht beurteilen, ob es wirklich nötig ist.

    2. Eine Möglichkeit suchen, Pfade case sensitive zu behandeln.
    Ich habe mal die File.Exists-Funktion im ILSpy angesehen. Leider habe ich nichts gefunden, womit man das case sensitive behandeln könnte.
    Also was eigenes erfinden.
    Vor Exceptions rate ich ab. Eine Exception zu werfen und zu fangen dauert relativ lange.
    Da ist das wesentlich performanter:

    VB.NET-Quellcode

    1. Private Shared Function FileExists(Path As String) As Boolean
    2. Dim Fi As New FileInfo(Path)
    3. 'Wenn die Datei so schon nicht existiert, wird sie sonst auch nicht gefunden.
    4. If Not Fi.Exists Then
    5. Return False
    6. End If
    7. For Each i In Fi.Directory.GetFiles
    8. 'Diese Pfade enthalten die exakte Groß-Kleinschreibung.
    9. If i.FullName = Path Then
    10. Return True
    11. End If
    12. Next
    13. Return False
    14. End Function
    Die Funktion müsste noch auf weitere Spezialfälle prüfen (Ordnerpfade, keine Rechte, etc.)
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Niko Ortner schrieb:

    (Edit: inzwischen wurde Post #7 gepostet.)

    Das Problem ist, dass wir nicht wissen, was Du machen willst (willst Du uns ja noch nicht sagen). Deshalb können wir nicht beurteilen, ob es wirklich nötig ist.



    Huch? Ich hab doch gesagt, was ich mache! Siehe Post #7

    Ich will Dateien per Dialog umbenennen oder moven. Beim MOVE brauche ich einen Verweis auf ein nicht existierendes Objekt. Beim RENAME kann das Object aber existieren. Nur die Schreibweise darf nicht EXAKT gleich sein.

    Das hab ich jetzt wie folgt gelöst:

    VB.NET-Quellcode

    1. 'New object does not exist
    2. If Not blnNewObjectExists Then Return RealToObject 'Accept new object
    3. 'New object exists
    4. If RealFromObject.ToUpper = RealToObject.ToUpper _
    5. AndAlso Not RealFromObject = RealToObject _
    6. AndAlso chrFunction = "R" Then _
    7. Return RealToObject 'Same but not identical names for rename - accept new object


    Also ich bin "perfectly happy" auch wenns vielleicht nicht so ganz verstanden wird. :) Eure Ratschläge haben mir sehr viel weiter geholfen. Manchmal muss man über Probleme einfach mal reden .... :)

    Danke nochmal an alle und
    LG
    Peter
    Ich will euch ja nicht enttäuschen, aber unter NTFS ist es sehr wohl möglich das eine C:\Test.txt und C:\TEST.txt Datei existiert, jedoch gestaltet sich der Zugriff auf diese mit einer Win32-Anwendung als schwierig. Mit dem Subsystem Interix (Microsoft Windows Services for UNIX) funktioniert das jedoch ohne Probleme.

    Weitere Infos:
    Dateinamen sind Groß-/ Kleinschreibung auf NTFS-Volumes
    Interix (Microsoft Windows Services for UNIX)
    Du könntest doch bei der Abfrage ob diese Datei schon existiert bei beiden ein .ToLower oder .ToUpper nutzen?!
    Somit solltest du doch keine Probleme bei der Existenz abfrage bekommen

    EDIT: hast doch schon ein .ToUpper drin übersehen, eigentlich sollte es doch jetzt keine Probleme mehr machen O.o
    Unfortunately, this Signature is not available in Germany because it may contain music for which GEMA
    has not granted the respective music rights. Sorry about that.

    Ich hab den Thread noch mal als unerledigt markiert.

    Das Problem der Behandlung von Groß- und Kleinbuchstaben bei Datei- und Verzeichnisnamen scheint mit im VB.Net nicht so ganz zufriedenstellend gelöst zu sein. Insbesondere wenn im Windows NT solche Namen unterschieden werden!

    Und im Rahmen dieser Problematik stoße ich jetzt auf das nächste Problem: mein RENAME Befehlt scheitert!

    VB.NET-Quellcode

    1. My.Computer.FileSystem.RenameFile(RealOldObject, RealNewFile)


    Wenn RealOldObject = "C:\test.txt" und RealNewfile="TEST.TXT" gesetzt ist, dann wirft der Rename Befehl eine IOException, wegen bereits vorhandenem Dateinamens, obwohl das doch eine ganz legale Operation sein sollte!

    So wie ich das sehen, muss ich jetzt die Datei erst mal auf einen Zwischenname umbenennen, etwa "$$$$$$text.txt" und erst dann kann ich zur finalen Umbenennung schreiten.

    Das ist alles andere als befriedigend! Besser wäre es schon, wenn die Namen case sensitive behandelt würden ... aber mir scheint das iss halt nich so im VB.Net! :(

    Irgendwelche schlauen Ideen?

    LG
    Peter
    @Peter329 zudem verstehe ich nicht was du dir davon erhoffst ob deine Datei nun "TEST.TXT" oder "test.txt" heißt.
    Wenn Du zb. auf die Datei verknüpfst spielt (eigentlich) die groß/Kleinschreibung keine Rolle!
    Unfortunately, this Signature is not available in Germany because it may contain music for which GEMA
    has not granted the respective music rights. Sorry about that.

    jvbsl schrieb:

    @slice: natürlich ist es möglich, aber nicht vorgesehen...


    Ehe die Diskussion in die falsche Richtung geht: ich habe NICHT vor Dateien zu erstellen, die sich nur durch Groß- und Kleinschreibung unterscheiden. Alle meine Files haben verschiedene Namen - auch non-case sensitive.

    Aber ich will schon eine Datei, die als TEST.TXT angeliefert wurde, in test.txt umbenennen können! z.B. Damit die Namen in meinen Verzeichnissen einheitlich sind! Dies ist inbesondere wichtig im Hinblick auf die Sortierreihenfolge bei umfangreichen Verzeichnissen!

    Und für einen solchen Rename suche ich eine Lösung, die OHNE Trickserei auskommt!
    ohne Trickserei ist mir nix bekannt. Ich hätte den Fehler auch weniger im VB verortet als im Windows-Dateisystem, was scheinbar nicht case-sensitiv ist - da kann vb ja nix für.

    Also der Trick - falls du ihn dir nicht schon selbst ausgedacht hast: Wenn die Namen case-sensitiv unterschiedlich, aber case-insensitiv gleich sind: Move die Datei auf einen temporären Namen, der bestimmt nicht existiert, und move sie dann so, wie du sie heißen haben willst.
    Ist bisserl umständlich, und wenn das massenhaft auftritt lässt sich da evtl. auch noch was optimieren.
    @Peter329 Das geht ganz easy ohne zu tricksen:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim fi = New IO.FileInfo("C:\Temp\_Test\TEST.TXT")
    3. fi.MoveTo("C:\Temp\_Test\test.txt")
    4. End Sub
    Bilder
    • vorher.jpg

      3,25 kB, 233×95, 1.795 mal angesehen
    • nachher.jpg

      2,87 kB, 167×85, 1.716 mal angesehen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    @Peter329 Das geht ganz easy ohne zu tricksen:


    WOW! Supi!

    Das ist natürlich KLASSE ... jetzt schmeiß ich meinen rekursiven Quatsch weg und mach das genauso wie von dir vorgeschlagen!

    Ich heb ja grundsätzlich meinen Daumen, wie ihr wisst! Schade, dass ich für DIESEN Tipp nicht mindestens ein Dutzend Mal meinen Daumen heben kann!
    :)

    Du hast mein Weltbild gerettet, RFG! :)

    LG
    Peter

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Peter329“ ()