mightymax
mightymax

Reputation: 431

VB.net Check items in a text doc and see if it's in a folder

I have a text document with a list of file names and their extensions. I need to go through this list and check a directory for the existence of each file. I then need to output the result to either foundFilesList.txt or OrphanedFiles.txt. I have two approaches to this function, and neither is working. The first example uses a loop to cycle through the text doc. The second one doesn't work it never sees a match for the file from the fileNamesList.

Thank you for taking the time to look at this.

First Code:

    Dim FILE_NAME As String

    FILE_NAME = txtFileName.Text
    Dim fileNames = System.IO.File.ReadAllLines(FILE_NAME)
    fCount = 0
    For i = 0 To fileNames.Count() - 1
        Dim fileName = fileNames(i)
        'sFileToFind = location & "\" & fileName & "*.*"

        Dim paths = IO.Directory.GetFiles(location, fileName, IO.SearchOption.AllDirectories)
        If Not paths.Any() Then
            System.IO.File.AppendAllText(orphanedFiles, fileName & vbNewLine)
        Else
            For Each pathAndFileName As String In paths
                If System.IO.File.Exists(pathAndFileName) = True Then
                    Dim sRegLast = pathAndFileName.Substring(pathAndFileName.LastIndexOf("\") + 1)
                    Dim toFileLoc = System.IO.Path.Combine(createXMLFldr, sRegLast)
                    Dim moveToFolder = System.IO.Path.Combine(MoveLocation, "XML files", sRegLast)

                    'if toFileLoc = XML file exists move it into the XML files folder
                    If System.IO.File.Exists(toFileLoc) = False Then
                        System.IO.File.Copy(pathAndFileName, moveToFolder, True)
                        System.IO.File.AppendAllText(ListofFiles, sRegLast & vbNewLine)
                        fileFilename = (fileName) + vbCrLf
                        fCount = fCount + 1
                        BackgroundWorker1.ReportProgress(fCount)
                        'fileCount.Text = fCount
                    End If
                End If
            Next
        End If
        BackgroundWorker1.ReportProgress(100 * i / fileNames.Count())
        'statusText = i & " of " & fileName.Count() & " copied"
        fCount = i
    Next

Second Code:

    FILE_NAME = txtFileName.Text    'textfield with lines of filenames are located ]
    Dim fileNamesList = System.IO.File.ReadAllLines(FILE_NAME)
    location = txtFolderPath.Text
    fCount = 0


    ' Two list to collect missing and found files
    Dim foundFiles As List(Of String) = New List(Of String)()
    Dim notfoundFiles As List(Of String) = New List(Of String)()

    Dim fileNames As String() = System.IO.Directory.GetFiles(createXMLFldr)
    For Each file As String In fileNamesList
        Debug.Write("single file : " & file & vbCr)
        ' Check if the files is contained or not in the request list 
        Dim paths = IO.Directory.GetFiles(location, file, IO.SearchOption.AllDirectories)
        If fileNamesList.Contains(Path.GetFileNameWithoutExtension(file)) Then

            Dim FileNameOnly = Path.GetFileName(file)
            Debug.Write("FileNameOnly " & FileNameOnly & vbCr)
            If System.IO.File.Exists(FileNameOnly) = True Then
                'if toFileLoc = XML file exists move it into the XML files folder
                Dim moveToFolder = System.IO.Path.Combine(MoveLocation, "XML files", file)
                foundFiles.Add(file) 'add to foundFiles list                        
                fileFilename = (file) + vbCrLf  'add file name to listbox
                fCount = fCount + 1
            Else
                notfoundFiles.Add(file)
            End If
        End If
    Next
    File.WriteAllLines(ListofFiles, foundFiles)
    File.WriteAllLines(orphanedFiles, notfoundFiles)

Upvotes: 0

Views: 232

Answers (2)

Mary
Mary

Reputation: 15081

Explanations and comments in-line.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    'I presume txtFileName.Text contains the full path including the file name
    'I also presume that this text file contains only file names with extensions
    Dim FilesInTextFile = System.IO.File.ReadAllLines(txtFileName.Text)
    'Instead of accessing the Directory over and over, just get an array of all the files into memory
    'This should be faster than searching the Directory structure one by one
    'Replace <DirectoryPathToSearch> with the actual path of the Directory you want to search
    Dim FilesInDirectory = IO.Directory.GetFiles("<DirectoryPathToSearch>", "*.*", IO.SearchOption.AllDirectories)
    'We now have an array of full path and file names but we just need the file name for comparison
    Dim FileNamesInDirectory = From p In FilesInDirectory
                               Select Path.GetFileName(p)
    'A string builder is more efficient than reassigning a string with &= because a 
    'string build is mutable
    Dim sbFound As New StringBuilder
    Dim sbOrphan As New StringBuilder
    'Instead of opening a file, writing to the file and closing the file 
    'in the loop, just append to the string builder
    For Each f In FilesInTextFile
        If FileNamesInDirectory.Contains(f) Then
            sbFound.AppendLine(f)
        Else
            sbOrphan.AppendLine(f)
        End If
    Next
    'After the loop write to the files just once.
    'Replace the file path with the actual path you want to use
    IO.File.AppendAllText("C:\FoundFiles.txt", sbFound.ToString)
    IO.File.AppendAllText("C:\OrphanFiles.txt", sbOrphan.ToString)
End Sub

Upvotes: 1

InteXX
InteXX

Reputation: 6367

This is just a starting point for you, but give it a try:

Friend Module Main
  Public Sub Main()
    Dim oFiles As List(Of String)

    Dim _
      sOrphanedFiles,
      sSearchFolder,
      sFoundFiles,
      sTargetFile As String

    sOrphanedFiles = "D:\Results\OrphanedFiles.txt"
    sSearchFolder = "D:\Files"
    sFoundFiles = "D:\Results\FoundFiles.txt"
    oFiles = IO.File.ReadAllLines("D:\List.txt").ToList

    oFiles.ForEach(Sub(File)
                     If IO.Directory.GetFiles(sSearchFolder, File, IO.SearchOption.AllDirectories).Any Then
                       sTargetFile = sFoundFiles
                     Else
                       sTargetFile = sOrphanedFiles
                     End If

                     IO.File.AppendAllText(sTargetFile, $"{File}{Environment.NewLine}")
                   End Sub)
  End Sub
End Module

If I've misjudged the requirements, let me know and I'll update accordingly.

Upvotes: 1

Related Questions