PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Visual Basic überprüfen ob Datei NICHT existiert.


Geldmann3
2013-01-18, 13:51:41
Ich schreibe gerade ein Programm in Microsoft Visual Basic 2010, welches eine Datei nur umbenennen soll, wenn der Dateiname, in welchen sie umbenannt werden soll logischerweise noch nicht existiert.

Das mache ich so

If System.IO.File.Exists(IO.Path.GetFileNameWithoutExtension(IO.Path.GetFileNameWit houtExtension(b) & "(HochQ)" & Dateierweiterung)) = False Then
My.Computer.FileSystem.RenameFile(b, IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung)

Die Datei soll also nur den neuen Namen erhalten, wenn "File.Exists" falsch ist, dieser also noch nicht existiert.

Doch das scheint so nicht zu funktionieren.
Wird eine Datei umbenannt, deren Zielname schon existiert, spuckt der Compiler
Der Vorgang konnte nicht abgeschlossen werden, da bereits eine Datei im Pfad D:\Dateiname.end vorhanden ist. aus.

Aber warum hat er überhaupt versucht es umzubennenen, wenn die Datei doch existiert, was ich zuerst abfragen wollte? Oder mache ich das Prüfen falsch?

Monger
2013-01-18, 14:28:50
IO.File.Exists erwartet eigentlich den vollständig qualifizierten Pfad, inklusive Ordner, Name und Endung. Dass du die alle wegschneidest ist also kontraproduktiv.

Ergo:

Dim NewFile = IO.Path.ChangeExtension(b, Dateierweiterung)
If NOT IO.File.Exists(NewFile) then IO.File.Move(b, NewFile)

Geldmann3
2013-01-18, 14:38:05
Ich muss mir den Name aber zusammenschneiden, weil es ihn ja eventuell noch gar nicht gibt.

IO.Path.ChangeExtension(b, Dateierweiterung)
Damit ändert man doch nur die Dateinamenerweiterung oder?

Diese soll aber gar nicht geändert werden, ich habe sie mir nur in eine Variable gepackt um den Dateinamen+Endung auseinander zunehmen um dann wiederum das "(HochQ)" vor die Endung zu quetschen.

Damit wiederum möchte ich dem String-Parsing aus dem Weg gehen.

IO.File.Exists erwartet eigentlich den vollständig qualifizierten Pfad, inklusive Ordner, Name und Endung. Dass du die alle wegschneidest ist also kontraproduktiv.

Warum, es bekommt doch einen vollständigen imaginären Pfad mit Endung und soll ja prüfen, ob dieser existiert?
IO.Path.GetFileNameWithoutExtension(IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung)
Dieser setzt sich aus (Pfad und Dateiname ohne Endung von b) & "(HochQ)" sowie der Dateinamenerweiterung zusammen. Ich liefere also einen vollständigen Pfad mit allem drum und dran, dessen Existenz nur noch überprüft werden soll.


Hier mal das Ziel:
Es soll die Datei umbenennen, sodass aus "Meinedatei.end" "Meinedatei(HochQ).end" wird. Das Hoch soll also vor die Endung gepackt werden. Dazu dachte ich mir, nehme ich einfach Endung und Pfad auseinander, und lasse das Programm letztendlich Pfad + Hoch + Endung wieder zusammensetzen. Der komplette Pfad wiederum ist in b weil das ganze in einer Schleife für viele Dateien läuft.

Monger
2013-01-18, 15:13:05
Warum, es bekommt doch einen vollständigen imaginären Pfad mit Endung und soll ja prüfen, ob dieser existiert?

Merk dir doch den String in einer Variable zwischen, und schau dir das ganze im Debugger an. Da kommt nie im Leben ein vollständiger, absoluter Pfad raus. Da fehlt mindestens mal der Laufwerksbuchstabe.

Geldmann3
2013-01-18, 15:18:14
Soweit ich sehe, ist der Pfad komplett, jedenfalls funktioniert die Umbenennung so mit Dateien, die nicht schon existieren.

Die Fehlermeldung lautet:
Der Vorgang konnte nicht abgeschlossen werden, da bereits eine Datei im Pfad D:\Eigene Musik\Videos\Dokumentationen\EinVideo(HochQ).mp4 vorhanden ist.

Da ist der Laufwerksbuchstabe jedenfalls dabei.

Nun habe ich versucht, die Existenz so zu prüfen:
If Not IO.File.Exists(IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung) Then
My.Computer.FileSystem.RenameFile(b, IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung)
Es soll also nur umbenannt werden, wenn die Datei noch nicht existiert, doch es passiert das Gleiche, die Datei wird umbenannt obwohl die Zieldatei schon existiert, was in der geschriebenen Fehlermeldung endet.
Die Überprüfung hat also irgendwie nicht geklappt.

Das Umbenennen funktioniert ja auch, jedenfalls wenn die Datei noch nicht existiert.

Und ich mache beides, prüfen und umbenennen mit "IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung"
Da der Pfad in der Fehlermeldung steht, scheint er ja richtig interpretiert zu werden. Nur warum funktioniert die Prüfung ob die Datei "IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung" schon existiert dann nicht?

Eigentlich müsste die Prüfung dann ja feststellen, dass die Datei nicht nicht exisitiert und auch erst gar nicht versuchen sie nochmal zu schreiben.

Denn es heisst ja
If Not IO.File.Exists

Monger
2013-01-18, 15:28:39
Die ganzen IO.File Operationen arbeiten grundsätzlich mal auch mit relativen Pfaden. In der Fehlermeldung spuckt er aber halt genau den Pfad raus den er überprüft. Pass also auf, dass du nicht aus Versehen auf relativen Pfaden arbeitest.

Geldmann3
2013-01-18, 15:38:13
Wie kann ich herausfinden, ob er mit einem relativen Pfad arbeitet?
Laut Fehlermeldung ergibt
IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung
ja den kompletten Pfad.

Und wie könnte ich ihn dann dazu bringen den kompletten Pfad zu benutzen?

Obwohl ich kaum glauben kann, dass er da plötzlich einen relativen Pfad benutzt...

Edit: Tatsächlich MSGBox gibt dabei nur

Ein Video(HochQ).mp4

aus.

Edit2: Funktioniert dennoch nicht. Obwohl ich jetzt den gesamten Pfad ermittle:
If Not IO.File.Exists(IO.Path.GetDirectoryName(b) & IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung) Then
My.Computer.FileSystem.RenameFile(b, IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung)
Er versucht umzubenennen obwohl (IO.Path.GetDirectoryName(b) & IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)) schon existiert.

Dabei frag ich doch If Not IO.File.Exists




Edit3: Um jetzt nochmal möglichst genau zu überprüfen was der Rechner macht, jetzt eine andere Variante, die auch nicht funktioniert. (temp ergibt den selben Pfad wie in der Fehlermeldung)

Dim temp As String
temp = IO.Path.GetDirectoryName(b) & IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung
MsgBox(temp)
If Not IO.File.Exists(temp) Then
My.Computer.FileSystem.RenameFile(b, IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung)

Es gibt wieder die selbe Fehlermeldung. Umbenennen unmöglich, weil Datei schon existiert.

Monger
2013-01-18, 17:22:16
Dim temp As String
temp = IO.Path.GetDirectoryName(b) & IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung
MsgBox(temp)
If Not IO.File.Exists(temp) Then
My.Computer.FileSystem.RenameFile(b, IO.Path.GetFileNameWithoutExtension(b) & "(HochQ)" & Dateierweiterung)

Oben bastelst du zwar den Pfad zusammen, aber unten lässt du den Verzeichnisnamen wieder aus (IO.Path.GetDirectoryName). Wer weiß, in was für ein Verzeichnis er da versucht zu schreiben.

Warum machst du immer so viel doppelt? Lange Rattenschwänze an Anweisungen sind auch immer eine potentielle Fehlerquelle. Und nenn Variablen nicht "b" oder "temp". Klingt zwar trivial, aber auch triviale Fehler können einen aufhalten.
Also:

Dim TargetFile = IO.Path.GetDirectoryName(SourceFile) & _
IO.Path.GetFileNameWithoutExtension(SourceFile) & "(HochQ)" & Dateierweiterung

MsgBox(TargetFile)
If not IO.File.Exists(TargetFile) Then
IO.File.Move(SourceFile, TargetFile)
End If

Geldmann3
2013-01-18, 18:48:45
Danke, deine Variante scheint zu funktionieren. Also merken, am besten immer Variablen verwenden, unter denen man sich etwas vorstellen kann.

Warum verwendest du Move?

Edit: Dachte schon es würde die Dateien löschen, doch du hattest du einen "\" vergessen. (;

Monger
2013-01-18, 20:19:09
"My.Computer.FileSystem.RenameFile" ist in einer VB.NET-spezifischen Assembly. Man hat da wohl versucht, sich ein bißchen an die Syntax anzulehnen die es in VB6 gab, aber im Endeffekt wird da im Hintergrund wahrscheinlich auch nur "Move" aufgerufen. Da ich öfters mal zwischen C# und VB.NET hin und herspringe, habe ich mir halt angewöhnt, die sprachneutrale Variante zu benutzen. Außerdem liegt ja im IO Namespace auch alles andere was man üblicherweise so braucht.

Unter NTFS bzw. Fat32 ist ein Umbenennen de facto nichts anderes als ein Verschieben in den selben Ordner mit anderem Namen. Deshalb gibt es in der IO.File Klasse keine eigenständige Funktion für umbenennen - Move ist viel flexibler und allgemeiner.

Gast
2013-01-19, 11:34:07
vielleicht hilft dir auch noch die FileInfo-Klasse weiter