Hello Daniweb,

I need to write a program to change the extension of all the files in a folder from a certain extension to another.
My code is shown below, however, I have one problem:
i.e.
Say we want to change all files with the extension ".tx" to ".txt" but there are two files
of the same name but one file ends with ".tx" and the other ends with ".txt"
****************************(in the folder: one.txt and one.tx)*******************
Now I have to rename the ".txt" file after it has been changed to the ".txt" file...****

How can I do this correctly and without error?

Public Class Form1.
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else

            Dim files As String()
            files = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.tx")
            Dim filepath_new As String

            For Each filepath As String In files

                filepath_new = filepath.Replace(".tx", ".txt")
                If Not My.Computer.FileSystem.FileExists(filepath_new) = True Then
                    My.Computer.FileSystem.RenameFile(filepath, filepath_new)
                Else
                    Dim iRenamed As Integer = 0
                    '///////////////////////////////////////////////////////////////////////
                    Dim iFileCopyNumber As Integer = 1 '// ADDED THIS.
                    '///////////////////////////////////////////////////////////////////////
                    With My.Computer.FileSystem
                        '  For Each foundFile As String In .GetFiles(TextBox1.Text.Trim(), FileIO.SearchOption.SearchAllSubDirectories, "*tx")
                        '// check if File already.Exists in Destination.Folder
                        'If Not System.IO.File.Exists(TextBox1.Text.Trim() & System.IO.Path.GetFileName(foundFile)) Then
                        '    System.IO.File.Move(filepath, filepath_new)
                        'Else '// If it Exists in Destination.Folder, .Rename.File
                        '    '///////////////////////////////////////////////////////////////////////
                        Do Until Not System.IO.File.Exists(TextBox1.Text.Trim() & System.IO.Path.GetFileNameWithoutExtension(filepath) & " - Copy (" & iFileCopyNumber.ToString & ")" & System.IO.Path.GetExtension(filepath))
                            iFileCopyNumber += 1
                        Loop
                        .RenameFile(filepath, System.IO.Path.GetFileNameWithoutExtension(filepath) & " - Copy (" & iFileCopyNumber.ToString & ")" & System.IO.Path.GetExtension(filepath))
                        iRenamed += 1
                        'iFileCopyNumber = iFileCopyNumber + 1
                        '///////////////////////////////////////////////////////////////////////
                        'End If
                        ' Next\
                        ' My.Computer.FileSystem.RenameFile(filepath, filepath_new)

                    End With
                    'Dim count As Integer = 1
                    'filepath_new = System.IO.Path.GetFileNameWithoutExtension(filepath_new) & count & System.IO.Path.GetExtension(filepath_new)
                    My.Computer.FileSystem.RenameFile(filepath, filepath_new)

                    'count = count + 1
                End If
                '' My.Computer.FileSystem.DeleteFile(filepath
                'System.IO.File.Move(filepath, filepath_new)
            Next
        End If
    End Sub


    Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim path As String = TextBox1.Text.Trim()
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            For Each foundfile As String In My.Computer.FileSystem.GetFiles _
(path, _
FileIO.SearchOption.SearchTopLevelOnly, "*.tx")
                ListBox1.Items.Add(foundfile)
            Next
        End If
    End Sub
End Class

Thanks in advance,
M1234ike

Hi M1234ike,
What you would need to do in this case is to do a search simular to what you have done but for all the .txt files in that directory. Then do the search as you are doing it now. while getting the .tx files do a compare to the list of .txt files to see if there is a file with that file name and if so rename the .tx file to incremented name, otherwise rename the extension. Below is one method of achieving this task.

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub


    Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim path As String = TextBox1.Text.Trim()
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            For Each foundfile As String In My.Computer.FileSystem.GetFiles(path, FileIO.SearchOption.SearchTopLevelOnly, "*.tx")
                ListBox1.Items.Add(foundfile)
            Next
        End If
    End Sub

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            Dim Newfile As String = "Copy - "
            Dim Exsitingfiles() As String
            Dim files As String()
            Dim filepath_new As String
            Exsitingfiles = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
            files = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.tx")
            For Each file As String In files
                filepath_new = file.Replace(".tx", ".txt")
                If Not Exsitingfiles.Contains(filepath_new) Then
                    Dim Filename() As String = Split(filepath_new, "\")
                    My.Computer.FileSystem.RenameFile(file, Filename(Filename.Count - 1))
                Else

                    Dim Filename() As String = Split(filepath_new, "\")
                    Filename(Filename.Count - 1) = Newfile & Filename(Filename.Count - 1)
                    My.Computer.FileSystem.RenameFile(file, Filename(Filename.Count - 1))
                End If
            Next
        End If
    End Sub
End Class

Curtis

The below code will help u to change the file extension...

Dim myFiles As String()
myFiles = IO.Directory.GetFiles("D:\", "*.txt")
Dim newFilePath As String
For Each filepath As String In myFiles
    newFilePath = filepath.Replace(".txt", ".html")
    System.IO.File.Move(filepath, newFilePath)
Next

I tried CurtisUN's suggestion and I received the attached error. test-error

Any hints?
Thanks in advance,
M1234ike

Oh: the error above is from running the program twice.

I copy over some ".tx" filesd to the test folder and run the program I recieve the error.

This is because: after running the program once the folder contains both: test.txt and text.txt-Copy(1).

When I copy over testy.tx into again the error pops up because test.txt-Copy(1) already exists.

I need to know how to increment test.txt-Copy(1) with a new name so this will work.

Any hints.
Thanks in advance,
M1234ike

Hi again,
I did some work on this and the method is a little complex. I have not fully tested this code but I have tested to make sure it does check and rename the files to names that does not exist. At least I have not run upon any errors yet.

Public Class Form1
    Dim FDCT As Integer = 0
    Dim FDC As Integer = 0
    Dim Newfile As String = "Copy - ("
    Dim ExsitingPaths() As String
    Dim Exsitingfilenames() As String
    Dim files As String()
    Dim filepath_new As String
    Dim Filename() As String
    Dim NameofFile As String = ""
    Dim SplitName As String = ""
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    End Sub
    Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim path As String = TextBox1.Text.Trim()
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            For Each foundfile As String In My.Computer.FileSystem.GetFiles(path, FileIO.SearchOption.SearchTopLevelOnly, "*.tx")
                ListBox1.Items.Add(foundfile)
            Next
        End If
    End Sub

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            ' get paths and filenames from directory
            Exsitingfilenames = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
            'newfilelist = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
            files = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.tx")
            'loop through directory of .tx files and test against .txt
            For Each file As String In files
                ' refresh directory on each loop
                ExsitingPaths = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
                For x = 0 To ExsitingPaths.Length - 1
                    Dim splitstring() As String = Split(ExsitingPaths(x), "\")
                    ReDim Preserve Exsitingfilenames(x)
                    Exsitingfilenames(x) = splitstring(splitstring.Length - 1)
                Next
                ' zero the primary name count (FDCT) and build variables for new filenames.
                FDCT = 0
                filepath_new = file.Replace(".tx", ".txt")
                'Get just the names of the files from the path
                Filename = Split(filepath_new, "\")
                NameofFile = Filename(Filename.Count - 1)
                'get the primary part of the name of the file
                If NameofFile.Contains("Copy -") Then
                    SplitName = NameofFile.Substring(0, NameofFile.Length - 14)
                Else
                    SplitName = NameofFile.Substring(0, NameofFile.Length - 4)
                End If
                'Check the existing files to see if copies exist and if so get the number of copies
                For x = 0 To Exsitingfilenames.Count - 1
                    Dim testname As String = Exsitingfilenames(x)
                    Dim Bool As Boolean = (testname.Contains(SplitName))
                    If Bool = True Then
                        FDCT += 1
                    End If
                Next
                'test to save file with correct filename
                If Not ExsitingPaths.Contains(filepath_new) Then
                    My.Computer.FileSystem.RenameFile(file, NameofFile)
                ElseIf FDCT > 0 Then 'A filename exists with this name that contains "copy" 
                    Dim Multifile As String
                    Multifile = Newfile & FDCT & ")"
                    Multifile = SplitName & Multifile & ".txt"
                    My.Computer.FileSystem.RenameFile(file, Multifile)
                End If
            Next
        End If
    End Sub

End Class

Curtis

Edited 4 Years Ago by CurtisUN: Removed some unused code

M1234ike after more testing I found that if some of the copies were deleted the app would error because the new file name would use a value less then the last copied value so I used Regex to retrieve the highest copy number for the new filename and all appears correct now.

Imports System.Text.RegularExpressions

Public Class Form1
    Dim FDCT As Integer = 1
    Dim FDC As Integer = 0
    Dim Newfile As String = "Copy - ("
    Dim ExsitingPaths() As String
    Dim Exsitingfilenames() As String
    Dim files As String()
    Dim filepath_new As String
    Dim Filename() As String
    Dim NameofFile As String = ""
    Dim SplitName As String = ""
    Dim copyvalue As Integer
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    End Sub
    Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim path As String = TextBox1.Text.Trim()
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            For Each foundfile As String In My.Computer.FileSystem.GetFiles(path, FileIO.SearchOption.SearchTopLevelOnly, "*.tx")
                ListBox1.Items.Add(foundfile)
            Next
        End If
    End Sub

    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            ' get paths and filenames from directory
            Exsitingfilenames = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
            'newfilelist = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
            files = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.tx")
            'loop through directory of .tx files and test against .txt
            For Each file As String In files
                ' refresh directory on each loop
                ExsitingPaths = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
                For x = 0 To ExsitingPaths.Length - 1
                    Dim splitstring() As String = Split(ExsitingPaths(x), "\")
                    ReDim Preserve Exsitingfilenames(x)
                    Exsitingfilenames(x) = splitstring(splitstring.Length - 1)
                Next
                ' zero the primary name count (FDCT) and build variables for new filenames.
                FDCT = 1
                filepath_new = file.Replace(".tx", ".txt")
                'Get just the names of the files from the path
                Filename = Split(filepath_new, "\")
                NameofFile = Filename(Filename.Count - 1)
                'get the primary part of the name of the file
                If NameofFile.Contains("Copy -") Then
                    SplitName = NameofFile.Substring(0, NameofFile.Length - 14)
                Else
                    SplitName = NameofFile.Substring(0, NameofFile.Length - 4)
                End If
                'Check the existing files to see if copies exist and if so get the last number of copy used
                For x = 0 To Exsitingfilenames.Count - 1
                    Dim testname As String = Exsitingfilenames(x)
                    Dim Bool As Boolean = (testname.Contains("Copy -"))
                    If Bool = True Then
                        copyvalue = CInt(Regex.Replace(testname, "[^0-9.]", String.Empty).Trim())
                        If FDCT <= copyvalue Then
                            FDCT = copyvalue + 1
                        End If
                    End If
                Next
                'test to save file with correct filename
                If Not ExsitingPaths.Contains(filepath_new) Then
                    My.Computer.FileSystem.RenameFile(file, NameofFile)
                Else
                    Dim Multifile As String
                    Multifile = Newfile & FDCT & ")"
                    Multifile = SplitName & Multifile & ".txt"
                    My.Computer.FileSystem.RenameFile(file, Multifile)

                End If
            Next
        End If
    End Sub

End Class

Curtis

Hello Curtis,

I tried you code after recreating the ".tx" file "test -Copy(4)" and it renamed the file to: the file name plus a string of wierd numbers.
If you look at the attached picture of the folder I am running the code on you can see the problem:
...Copy(46) and Copy(447).
Do you know how to fix this?

Thanks,
M1234ike

text_tx

M1234ike,
I made a few modifications and think the code listed below will do better for what you are trying to accomplish. The 46 and 447 I could not duplicate the issue. so I don't have a clue as to where it came from. I made a few changes so if the filename contains "()" or "copy" it will get the primary filename and build a new filename with "copy ()" containing the highest copy number + 1. So you should not get any of the "Test copy(4) Copy(5).txt" type names at least i did not get any duplication of copy in the file name.

Imports System.Text.RegularExpressions
Public Class Form1
    Dim FDCT As Integer = 1
    Dim FDC As Integer = 0
    Dim Newfile As String = "Copy - ("
    Dim ExsitingPaths() As String
    Dim Exsitingfilenames() As String
    Dim files As String()
    Dim filepath_new As String
    Dim Filename() As String
    Dim NameofFile As String = ""
    Dim SplitName As String = ""
    Dim copyvalue As Integer
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    End Sub
    Private Sub Button2_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim path As String = TextBox1.Text.Trim()
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            For Each foundfile As String In My.Computer.FileSystem.GetFiles(path, FileIO.SearchOption.SearchTopLevelOnly, "*.tx")
                ListBox1.Items.Add(foundfile)
            Next
        End If
    End Sub
    Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If Not My.Computer.FileSystem.DirectoryExists(TextBox1.Text.Trim()) = True Or TextBox1.Text.Trim() = "" Then
            MsgBox("Please enter a valid directory.")
        Else
            ' get paths and filenames from directory
            Exsitingfilenames = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
            'newfilelist = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
            files = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.tx")
            'loop through directory of .tx files and test against .txt
            For Each file As String In files
                ' refresh directory on each loop
                ExsitingPaths = IO.Directory.GetFiles(TextBox1.Text.Trim(), "*.txt")
                For x = 0 To ExsitingPaths.Length - 1
                    Dim splitstring() As String = Split(ExsitingPaths(x), "\")
                    ReDim Preserve Exsitingfilenames(x)
                    Exsitingfilenames(x) = splitstring(splitstring.Length - 1)
                Next
                ' zero the primary name count (FDCT) and build variables for new filenames.
                FDCT = 1
                filepath_new = file.Replace(".tx", ".txt")
                'Get just the names of the files from the path
                Filename = Split(filepath_new, "\")
                NameofFile = Filename(Filename.Count - 1)
                'get the primary part of the name of the file
                If NameofFile.Contains("Copy") Then
                    SplitName = NameofFile.Substring(0, NameofFile.Length - 14)
                Else
                    SplitName = NameofFile.Substring(0, NameofFile.Length - 4)
                End If
                'Check the existing files to see if copies exist and if so get the last number of copy used
                For x = 0 To Exsitingfilenames.Count - 1
                    Dim testname As String = Exsitingfilenames(x)
                    Dim Bool As Boolean = (testname.Contains("Copy" & "(" & ")"))
                    If Bool = True Then
                        copyvalue = CInt(Regex.Replace(testname, "[^0-9.]", String.Empty).Trim())
                        If FDCT <= copyvalue Then
                            FDCT = copyvalue + 1
                        End If
                    ElseIf testname.Contains("Copy") Then
                        FDCT += 1
                    End If
                Next
                'test to save file with correct filename
                If Not ExsitingPaths.Contains(filepath_new) Then
                    My.Computer.FileSystem.RenameFile(file, NameofFile)
                Else
                    Dim Multifile As String
                    Multifile = Newfile & FDCT & ")"
                    Multifile = SplitName & Multifile & ".txt"
                    My.Computer.FileSystem.RenameFile(file, Multifile)
                End If
            Next
        End If
    End Sub
End Class

Curtis

In pseudo-code a suggested process is

get a list of all files with the given oldextension

for each oldfilename in the list
    basename = oldfilename stripped of the extension
    compose the newfilename as basename & "." & newextension
    set index = 0
    do while Exists(newfilename)
        increment index
        compose newfilename as basename & " " & index & "." & newextension
    loop
    rename oldfilename to newfilename
next
This article has been dead for over six months. Start a new discussion instead.