|
|
Title | Recursively search for files and replace text in them in Visual Basic .NET |
Description | This example shows how to recursively search for files and replace text in them in Visual Basic .NET. |
Keywords | files, directories, search, search for files, find files, replace, replacements, make replacements, Visual Basic .NET, VB.NET |
Categories | Files and Directories, Files and Directories |
|
|
This program recursively searches a directory subtree for files matching one or more patterns. Optionally it replaces instances of a target string in those files with a new string.
Both the Find and Find & Replace buttons call the SearchForFiles subroutine. The only difference is that the Find button passes that subroutine a null parameter for the "replace with" string.
The following code shows the SearchForFiles subroutine.
|
|
' Find files matching the pattern that contain the target
' string
' and make the replacement if appropriate.
Private Sub SearchForFiles(ByVal lst As ListBox, ByVal _
start_dir As String, _
ByVal pattern As String, ByVal from_string As String, ByVal _
to_string As String)
Try
' Clear the result ListBox.
lstFiles.Items.Clear()
' Parse the patterns.
Dim patterns() As String = ParsePatterns(pattern)
' If from_string is blank, don't replace.
If (from_string.Length < 1) Then from_string = _
Nothing
Dim dir_info As New DirectoryInfo(start_dir)
SearchDirectory(lst, dir_info, patterns, _
from_string, to_string)
If (from_string Is Nothing) Then
MessageBox.Show("Found " & lst.Items.Count & "" & _
"files.")
Else
MessageBox.Show("Made replacements in " & _
lst.Items.Count & " files.")
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
|
|
The SearchForFiles subroutine clears the program's result ListBox. It then calls ParsePatterns to convert the file search pattern into an array of patterns. For example, if the pattern is "Text Files (*.rtf, *.txt)" then ParsePatterns returns an array holding the values *.rtf and *.txt. (Parse pattern uses the String class's IndexOf, SubString, and Split methods. It's not too complex so it isn't shown here. Download the example and look at the code to see how it works.)
Next SearchForFiles creates a DirectoryInfo object representing the directory whose name the user entered. It then calls the SearchDirectory subroutine to do most of the real work.
The following code shows the SearchDirectory subroutine.
|
|
' Find files matching the pattern that contain the target
' string
' and make the replacement if appropriate.
Private Sub SearchDirectory(ByVal lst As ListBox, ByVal _
dir_info As DirectoryInfo, _
ByVal patterns() As String, ByVal from_string As String, _
ByVal to_string As String)
' Search this directory.
For Each pattern As String In patterns
' Check this pattern.
For Each file_info As FileInfo In _
dir_info.GetFiles(pattern)
' Process this file.
ProcessFile(lst, file_info, from_string, _
to_string)
Next file_info
Next pattern
' Search subdirectories.
For Each subdir_info As DirectoryInfo In _
dir_info.GetDirectories()
SearchDirectory(lst, subdir_info, patterns, _
from_string, to_string)
Next subdir_info
End Sub
|
|
First the subroutine processes this directory's files. For each file pattern, the code uses GetFiles to get the files that match the pattern. For each file, the code calls ProcessFile to process the file.
After it processes the files, the code loops through this directory's subdirectorys calling SearchDirectory for each.
The following code shows the ProcessFile subroutine.
|
|
' Replace all occurrences of from_string with to_string.
' Return true if there was a problem and we should stop.
Private Sub ProcessFile(ByVal lst As ListBox, ByVal _
file_info As FileInfo, ByVal from_string As String, _
ByVal to_string As String)
Try
If (from_string Is Nothing) Then
' Add the file to the list.
lst.Items.Add(file_info.FullName)
Else
' See if the file contains from_string.
Dim txt As String = _
System.IO.File.ReadAllText(file_info.FullName)
If (txt.Contains(from_string)) Then
' Add the file to the list.
lst.Items.Add(file_info.FullName)
' See if we should make a replacement.
If (to_string IsNot Nothing) Then
System.IO.File.WriteAllText(file_info.FullName, _
_
txt.Replace(from_string, to_string))
End If
End If
End If
Catch ex As Exception
MessageBox.Show("Error processing file " & _
file_info.FullName & "\n" & ex.Message)
End Try
End Sub
|
|
If from_string is null, the program should find all files without checking to see whether they contain a target string (because there isn't one). In that case, the program simply adds the file's name to the result ListBox.
If from_string is not null, the code reads the file into a string and sees whether it contains from_string. If the file does contain from_string, the code adds the file's name to the list. If to_string is also not null, the code replaces from_string with to_string in the text and writes the text back into the file.
The final piece that I'll mention here is the following, which executes when you double-click on the list of files found.
|
|
' Open the double-clicked file with the system's default
' application.
Private Sub lstFiles_DoubleClick(ByVal sender As Object, _
ByVal e As EventArgs) Handles lstFiles.DoubleClick
For Each selected_file As String In _
lstFiles.SelectedItems
System.Diagnostics.Process.Start(selected_file)
Next selected_file
End Sub
|
|
This code simply loops through the list's selected files and uses Process.Start to open each in the system's default application for the file.
Note that this code will try to read and process files that are not text files. For example, it will read RTF files. This will often succeed, although it may be confused by binary data or codes (such as RTF codes) in the file. Searching for files will probably still not cause problems, but you should be careful when you make replacements in non-text files because the program may mess up codes.
|
|
|
|
|
|