Dhan
Dhan

Reputation: 213

Check if String is a file or a folder VB.NET

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

Answers (4)

Case Slay
Case Slay

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

Visual Vincent
Visual Vincent

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

Cody Gray
Cody Gray

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

Mucahid Uslu
Mucahid Uslu

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

Related Questions