Frage von deeale, 147

VISUAL BASIC Pfad vervollständigen?

Hey Leute,

ich möchte mit einem Programm eine Datei in mehrere Ordner verschieben/kopieren. Das ganze klappt auch. Nur muss ich die Pfade manuell (alle relativ gleich) angeben. Ein Pfad sieht so aus Ordner/23432/local^ Also zwischen Ordner & local ist bei jedem Pfad eine unterschiedliche zahl..

Ich habe das ganze momentan so :

Dim ofDialog As New OpenFileDialog
            If ofDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
               
File.Copy(ofDialog.FileName, Path.Combine("Ordner/23432/local", Path.GetFileName(ofDialog.FileName)))
    
File.Copy(ofDialog.FileName, Path.Combine("Ordner/23432/local", Path.GetFileName(ofDialog.FileName)))

ich möchte dass das Programm die Datei die ich verschieben möchte immer in den Local Ordner rein verschiebt. Ist es denn möglich das Programm den Pfad zu vervollständigen lassen so das ich die Zahlen Ordner/23432/local nicht angeben muss sondern das Programm das ganze eigenständig macht?

Antwort
von CrystalixXx, 69

Sicherlich geht das. Mein erster Ansatz wäre alle Verzeichnisse von "Ordner" zu ermitteln. Dann iterierst du durch jeden dieser Verzeichnisse, fügst dein "local" dem Pfad an und kopierst deine Datei hinein.

For Each di In New System.IO.DirectoryInfo("Ordner").GetDirectories
Dim path As String = System.IO.Path.Combine(di.FullName, "local")
File.Copy(...)
Next

Schwieriger wird es, wenn in "Ordner" auch Verzeichnisse liegen, in welche nichts kopiert werden soll, weil der Ordername nicht deinen festgelegten Regeln entspricht. Dann musst du vorher erst dessen Name prüfen.

Kommentar von deeale ,
   Dim ofDialog As New OpenFileDialog

If ofDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
For Each di In New System.IO.DirectoryInfo("C:\Program Files (x86)\Steam\userdata\").GetDirectories
Dim path As String = System.IO.Path.Combine(di.FullName, "\730\local\cfg")
File.Copy(ofDialog.FileName, path.Combine("C:\Program Files (x86)\Steam\userdata\", path.GetFileName(ofDialog.FileName)))
Next

Hab das nun so, auch mit den richtigen Ordner Namen.. was genau hab ich falsch gemacht? Bin noch ganz am anfang mit dem coden..

Kommentar von CrystalixXx ,

Ändere die Zeile "Dim path ..." in folgende:

Dim path As String = System.IO.Path.Combine(di.FullName, "730\local\cfg", System.IO.Path.GetFileName(ofDialog.FileName))

Dann kannst du "File.Copy(...)" kürzen auf:

File.Copy(ofDialog.FileName, path)

Dein Problem lag aber in der Zeile mit "Dim path ..." im zweiten Argument. Du hast das zweite Argument mit einem Backslash (\) begonnen, was die Methode anweist den Pfad relativ zu betrachten und deswegen mit der Pfad-Zusammenführung an dieser Stelle erneut beginnt. Dadurch wird der erste absolute Pfad "vergessen".

Kommentar von deeale ,

Ja stimmt macht sinn mit dem \...

Das ganze scheint nun zu funktionieren? Die Dateien verschiebt er noch nicht, das denke ich liegt aber am Fehler den ich momentan noch bekomme. Manche Ordner nach /userdata/*random zahlen*/ haben keinen 730/local/cfg ordner.. 

Das Programm findet halt den Pfad nicht und spuckt dann einen Fehler aus^

Kommentar von deeale ,

Sobald ich die Ordner rausnehme die den 730 Ordner nicht haben funktioniert es.. gibt es denn eine Möglichkeit das anders zu lösen?


edit: und gibt es eine Möglichkeit das ich im explorer dann mehrere Dateien auf einmal auswählen kann?

Kommentar von CrystalixXx ,

Wie soll denn vorgegangen werden, wenn der Ordner nicht vorhanden ist? Entweder du erstellst den Ordner oder du ignorierst diesen. Prüfen kannst du es jedenfalls mit

System.IO.Directory.Exists(System.IO.GetDirectoryName(path))

Dann wäre aber wohl sinnvoll den Dateinamen nicht gleich in path zu schreiben.

Du kannst in einem OpenFileDialog auch mehrere Dateien auswählen. Die ausgewählten Dateien kannst du dann über ofDialog.FileNames abfragen.

Kommentar von deeale ,

Am besten sollte es einfach ignoriert werden, den Ordner zu erstellen wäre weniger sinnvoll. 

GetFileNames geht bei mir nicht, nur GetFileName.. 


Kann über den OpenFileDialog nur eine Datei auswählen. Mit STRG mehrere auswählen funktioniert bei mir nicht^^

Welchen Pfad müsste ich den bei Directory.Exists eingeben? einfach nur 730/local/cfg?

Kommentar von CrystalixXx ,

Ich habe dir mal den ganzen Programmcode dazu geschrieben und etwas ausführlicher kommentiert, damit du die Umsetzung nachvollziehen kannst.

' Zielverzeichnis finden und ergänzen. Sollte das Zielverzeichnis nicht vorhanden sein,
' dann wird die Methode ohne weitere Aktion beendet.
Dim sourceDirectory As String = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)
sourceDirectory = System.IO.Path.Combine(sourceDirectory, "Steam\userdata")
If Not System.IO.Directory.Exists(sourceDirectory) Then Return

Using ofDialog As New OpenFileDialog
' Multiselect auf True festlegen, um dem Benutzer eine Mehrfach-Auswahl von Dateien
' zu ermöglichen.
ofDialog.Multiselect = True

If ofDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
' Iteriere durch alle Verzeichnisse, die im Zielverzeichnis vorhanden sind. Sollte
' das gewünschte Verzeichnis dort nicht vorhanden sein, wird die Methode ohne weitere
' Aktion beendet.
For Each di In New System.IO.DirectoryInfo(sourceDirectory).GetDirectories
Dim filePath As String = System.IO.Path.Combine(di.FullName, "730\local\cfg")
If Not System.IO.Directory.Exists(filePath) Then Return

' Iteriere durch alle vom Benutzer ausgewählten Dateien und speichere den
' Dateinamen und den vollständigen Dateinamen (Pfad und Dateiname) in eine
' eigene Variable (ermöglicht eine spätere Verwendung, z.B. durch weitere
' Prüf-Methoden). Kopiere anschließend die Datei ins Zielverzeichnis.
For Each file In ofDialog.FileNames
Dim fileName As String = System.IO.Path.GetFileName(file)
Dim fullName As String = System.IO.Path.Combine(filePath, fileName)

System.IO.File.Copy(file, fullName)
Next
Next
End If
End Using
Kommentar von deeale ,

Jetzt hast du mich voll aus dem Konzept gebracht lach

Brauch ich denn das alles was du jetzt gepostet hast ?

Ich möchte eine Datei in den cfg Ordner reinkopieren, bzw in alle cfg 730/local/cfg ordner die vorhanden sind. Davor hat es geklappt.. jetzt nicht mehr <.>

Kommentar von CrystalixXx ,

Oh, da ist mir ein kleiner Denkfehler unterlaufen.

' Zielverzeichnis finden und ergänzen. Sollte das Zielverzeichnis nicht vorhanden sein,
' dann wird die Methode ohne weitere Aktion beendet.
Dim sourceDirectory As String = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles)
sourceDirectory = System.IO.Path.Combine(sourceDirectory, "Steam\userdata")
If Not System.IO.Directory.Exists(sourceDirectory) Then Return

Using ofDialog As New OpenFileDialog
' Multiselect auf True festlegen, um dem Benutzer eine Mehrfach-Auswahl von Dateien
' zu ermöglichen.
ofDialog.Multiselect = True

If ofDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
' Iteriere durch alle Verzeichnisse, die im Zielverzeichnis vorhanden sind. Sollte
' das gewünschte Verzeichnis dort nicht vorhanden sein, wird der Ordner übersprungen
' und mit dem nächsten weiter gemacht.
For Each di In New System.IO.DirectoryInfo(sourceDirectory).GetDirectories
Dim filePath As String = System.IO.Path.Combine(di.FullName, "730\local\cfg")

If System.IO.Directory.Exists(filePath) Then
' Iteriere durch alle vom Benutzer ausgewählten Dateien und speichere den
' Dateinamen und den vollständigen Dateinamen (Pfad und Dateiname) in eine
' eigene Variable (ermöglicht eine spätere Verwendung, z.B. durch weitere
' Prüf-Methoden). Kopiere anschließend die Datei ins Zielverzeichnis.
For Each file In ofDialog.FileNames
Dim fileName As String = System.IO.Path.GetFileName(file)
Dim fullName As String = System.IO.Path.Combine(filePath, fileName)

System.IO.File.Copy(file, fullName)
Next
End If
Next
End If
End Using

Die Methode wurde beendet, sobald ein Ordner gefunden wurde, in dem der 730-Order etc. nicht vorhanden war. Das ist natürlich Unfug, weil die anderen Ordner diesen ja schließlich beinhalten könnten.

Ich habe den Code insofern lediglich flexibler und sicherer gestaltet. Ansonsten macht er genau das, was du möchtest. : )

Kommentar von deeale ,

Super, Danke! 

Zu aller letzt : wie überschreibe ich die Datei wenn sie schon vorhanden ? 

 For Each foundFile In

My.Computer.FileSystem.GetFiles("C:\Program Files (x86)\Steam\userdata")
foundFile = foundFile & vbCrLf
My.Computer.FileSystem.WriteAllText(
"730\local\cfg", foundFile, True)

so in der art sollte das doch funktionieren

Kommentar von CrystalixXx ,

Wenn du meinen Code benutzt, dann kannst du die Zeile zum Kopieren durch

System.IO.File.Copy(file, fullName, True)

ersetzen.

Ich persönlich halte überhaupt nichts vom My-Namespace. Meiner Ansicht nach bringt der die Framework-Struktur durch überflüssige Kompatibilitätsgründen durcheinander. Die darin enthaltenen Klassen und Methoden wirken obendrein irgendwie gefrickelt.

Kommentar von deeale ,

Super, vielen lieben dank! 

Wenn ich jetzt eine datei einfüge die den selben namen hat, kann ich das dann so machen das die alte Datei z.B. configbackup1 heißt? Google bringt mich nicht weiter, finde nur sachen die nicht zum thema passen oder ich lese direkt am thema vorbei

Kommentar von CrystalixXx ,

Na klar geht das. Dann müsstest du vor dem Kopier-Befehl prüfen, ob die Datei schon vorhanden ist (z.B. mit System.IO.File.Exists). Wenn ja, dann musst du diese vorher umbenennen (System.IO.File.Move), wenn nicht, kannst du einfach kopieren. Das schaffst du aber sicherlich auch alleine. ; )

Kommentar von deeale ,

Ich komm nicht so ganz drauf, habs auch mit Replace versucht klappt aber auch nicht so richtig.. hast du noch einen kleinen tipp der mir auf die sprünge helfen könnte?

Kommentar von deeale ,

Das jede Datei einen anderen Pfad hat bringt mir total durcheinander

Kommentar von CrystalixXx ,

Eigentlich habe ich dir eine schrittweise Vorgehensweise beschrieben und die jeweiligen Methoden genannt.

If System.IO.File.Exists(fullName) Then
System.IO.File.Move(fullName, System.IO.Path.Combine(filePath, System.IO.Path.GetFileNameWithoutExtension(fileName) & "1" & System.IO.Path.GetExtension(fileName)))
Else
System.IO.File.Copy(file, fullName, True)
End If

Damit wird einer vorhandenen Datei im Namen eine 1 angefügt. Wenn du den Wert hochzählen lassen willst, vor allem in einer bestimmten Reihenfolge, dann wird es deutlich komplizierter und wäre dann rekursiv zu lösen. Dafür solltest du aber eine neue Frage stellen.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten