Reputation: 213
How do you check if a String
value is a folder or a file? I'm using FileSystemWatcher
to check for the changes in a file or a folder then I'm storing it in a List(Of String)
with this code:
Private Sub logrename(ByVal source As Object, ByVal e As System.IO.RenamedEventArgs)
oldfldrnme.Add(e.OldName)
newfldrnme.Add(e.Name)
End Sub
Using this code:
Dim dest As String = Label6.Text
For i = 0 To oldfldrnme.Count - 1 And newfldrnme.Count - 1
Dim attri As FileAttribute = File.GetAttributes(i)
If ((attri And FileAttribute.Directory) = FileAttribute.Directory) Then
Microsoft.VisualBasic.FileIO.FileSystem.RenameDirectory(dest & "\" & oldfldrnme(i), newfldrnme(i))
Else
Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(dest & "\" & oldfldrnme(i), newfldrnme(i))
End If
Next
FileNotFound Exception
throws, with this line Visual Studio 2010\Projects\File Sync2\File Sync\bin\Debug\0'.
but with this code:
For i = 0 To oldfldrnme.Count - 1 And newfldrnme.Count - 1
Dim ex As String = Path.HasExtension(i)
If ex = False Then
Microsoft.VisualBasic.FileIO.FileSystem.RenameDirectory(dest & "\" & oldfldrnme(i), newfldrnme(i))
Else
Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(dest & "\" & oldfldrnme(i), newfldrnme(i))
End If
Next
work with directories, but with files it tells that it's a directory, throwing DirectoryNotFoundException
with this line Could not find directory 'D:\Test2\New Text Document.txt'.
Upvotes: 1
Views: 9115
Reputation: 3
You could try this:
Imports System.IO
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
Listfolders(TextBox1.Text) 'Call Public Sub ListFolders
End Sub
Public Sub Listfolders(ByVal Path As String) 'Path is Texbox1.Text
Dim DirInfo As New IO.DirectoryInfo(Path) 'C:\!Testfolder
Dim FileObject As IO.FileSystemInfo
For Each FileObject In DirInfo.GetFileSystemInfos 'fileobject is file or folder
If FileObject.Attributes = IO.FileAttributes.Directory Then
'Fileobject is Folder
Listfolders(FileObject.FullName) 'Use public Sub again to find folders and files in subfolders
ListBox1.Items.Add(FileObject.Name) 'Add folder to listbox
Else
'Fileobject is file
ListBox1.Items.Add(FileObject.Name) 'Add file to listbox
End If
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1.Text = "C:\!TestFolder" 'Give initial text to Textbox1
End Sub
End Class
Upvotes: 0
Reputation: 18320
First of all, you cannot use And
in a For Next
statement. That causes you to bitwise combine your two integers.
Secondly, there is a possibility that files do not have an extension, so checking Path.HasExtension()
could at some point throw an exception.
Thirdly, to concatenate path's together you are better of using IO.Path.Combine()
.
So first we take care of the bitwise combining statement. Using Math.Min()
you will get the lowest of the two values (which you must, because if one for some reason has more items than the other, your code would throw an IndexOutOfRangeException
).
For i = 0 To Math.Min(oldfldrnme.Count, newfldrnme.Count) - 1
Now let's check if the path is a file or not. You cannot do Directory.Exists(i)
because i
is your Integer variable, not a complete path. To correctly check it you must do Directory.Exists(<path to be renamed>)
. We use IO.Path.Combine()
to correctly get the destination path.
For i = 0 To Math.Min(oldfldrnme.Count, newfldrnme.Count) - 1
Dim DestPath As String = Path.Combine(dest, oldfldrnme(i)) 'This is the file/directory to be renamed.
If File.Exists(DestPath) Then
ElseIf Directory.Exists(DestPath) Then
End If
Next
Finally, we do the renaming.
For i = 0 To Math.Min(oldfldrnme.Count, newfldrnme.Count) - 1
Dim DestPath As String = Path.Combine(dest, oldfldrnme(i)) 'This is the file/directory to be renamed.
If File.Exists(DestPath) Then
Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(DestPath, newfldrnme(i))
ElseIf Directory.Exists(DestPath) Then
Microsoft.VisualBasic.FileIO.FileSystem.RenameDirectory(DestPath, newfldrnme(i))
End If
Next
EDIT:
And as Cody Gray noted, you should probably add some exception handling to the code in case of something else performing I/O operations with your files/directories.
So we'll be adding a Try Catch
statement around the renaming operations. In case of that an error occurs the Catch
blocks will be executed, meaning that you don't have the issue of your whole application stopping.
For i = 0 To Math.Min(oldfldrnme.Count, newfldrnme.Count) - 1
Dim DestPath As String = Path.Combine(dest, oldfldrnme(i)) 'This is the file/directory to be renamed.
If File.Exists(DestPath) Then
Try
Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(DestPath, newfldrnme(i))
Catch ex As Exception
'Log error using ex.Message. For example "Could not rename file: " & ex.Message
End Try
ElseIf Directory.Exists(DestPath) Then
Try
Microsoft.VisualBasic.FileIO.FileSystem.RenameDirectory(DestPath, newfldrnme(i))
Catch ex As Exception
'Log error using ex.Message. For example "Could not rename folder: " & ex.Message
End Try
End If
Next
Upvotes: 3
Reputation: 244981
The GetAttributes
function will throw an exception if called on an item that doesn't exist. How could it possibly do otherwise? Something that doesn't exist has no attributes. As such, it is not a general solution for checking whether something exists.
You will need to use the Exists
method. For example:
Public Enum FileSystemObject
InvalidPath
Directory
File
End Enum
Public Function WhatIsThisThing(String path) As FileSystemObject
If Directory.Exists(path) Then
Return FileSystemObject.Directory
Else If File.Exists(path)
Return FileSystemObject.File
Else
Return FileSystemObject.InvalidPath
End If
End Function
However, you still have a possible race condition here, as you always do when performing file I/O. Performing the check before-hand is fine, but you also need to handle exceptions that might be thrown when you try to rename the object. You have no way of ensuring that the file or folder isn't deleted or renamed in between the time that you check its existence and the time that you issue the rename command.
Upvotes: 2
Reputation: 417
Use to check path/file exists in VB.NET,
If File.Exists(strPath) Then
' yes this is a file
Else
' oh no
End If
Upvotes: 0