Why System.IO.File.Exists doesn't take if else statement - vb.net

I have if condition issues when running the following code for an image file:
Dim mainFolder As String = "\\Users\No_Image_Available.png"
Dim saveDirectory As String = "\\IMAGE\"
Dim Filename As String = System.IO.Path.GetFileName(mainFolder)
Dim mainSavePath As String = System.IO.Path.Combine(saveDirectory, Filename)
If System.IO.File.Exists(mainSavePath) Then
'do nothing
Else
'file doesn't exist
My.Computer.FileSystem.CopyFile("\\Users\No_Image_Available.png", "\\IMAGES\No_Image_Available.png")
End If
If the file doesn't exist then it will accept the if statements by either IF Not exist or IF exist... however, if the file already exist it will take the copy argument whether it is in the right if condition or not.
Why is that? It is as if it still reads and accepts the first 'do nothing' condition regardless.
FYI- the paths you see are fake

Issue was that they were server directories. I made the corrections that worked.
Dim Filename = "No_Image_Available.png"
Dim savePathcopy As String = Server.MapPath("~/IMAGES/")
Dim pathToCheckCopy As String = savePathcopy + Filename
'Dim mainSavePath As String = System.IO.Path.Combine(saveDirectory, Filename)
If (System.IO.File.Exists(pathToCheckCopy)) Then
' If System.IO.File.Exists(noImg) = True Then
Else
'file doesn't exist
My.Computer.FileSystem.CopyFile("\\..\Dev\web\WebUsers\...\..\Classified_Ads_V2\No_Image_Available.png", "\\...\Dev\web\WebUsers\...\..\...\IMAGES\No_Image_Available.png")
End If

Related

GetFiles is incredibly slow vb.NET

I need to process a large amount of files and scour thru a group of directories and subdirectories and get the file from the found directory. This is easy using a simple directory but when scouring a thousand directories, the program slows down to a crawl. I've heard of using enumeratefiles but I'm not how to approach this. thank you.
How should I approach this?
dim Filename_to_lookfor as string
dim filePaths As String()
for i = 0 to 1000
Filename_to_lookfor = array(i)
filePaths = Directory.GetFiles(sTargetPath, sFilename_to_lookfor.ToUpper,
IO.SearchOption.AllDirectories)
if filepath.length > 0 then
'copy file using Computer.FileSystem.CopyFile()
end if
next
Thank you.
Another coding would be using Linq:
Sub SearchFiles(pathAndfileNames_to_lookfor() As String, sTargetPath As String)
' Call just once Directory.GetFiles():
Dim FilePaths() As String = Directory.GetFiles(sTargetPath, "*.*", IO.SearchOption.AllDirectories)
Dim lookup1 = FilePaths.ToLookup(Function(x) x.ToLower)
Dim lookup2 = pathAndfileNames_to_lookfor.ToLookup(Function(x) x.ToLower)
Dim filesInBoth = lookup1.SelectMany(Function(x) x.Take(lookup2(x.Key).Count).ToArray)
For Each file In filesInBoth
'copy file using Computer.FileSystem.CopyFile()
Console.WriteLine(file)
Next
End Sub
Calling the procedure would be as follows:
Dim file1 As String = "C:\...\file1..."
Dim file2 As String = "C:\...\file2..."
Dim pathAndfileNames_to_lookfor() As String = New String() {file1, file2}
Dim sTargetPath = "..."
SearchFiles(pathAndfileNames_to_lookfor, sTargetPath)

Text file split in blocks vb.net

I am trying to go through my text file and create a new file that will contain only the text I require. My current line looks like:
Car-1I
Colour-39
Cost-328
Dealer-28
Car-2
Colour-30
Cost-234
For each block of text I would like to read the first line, if the first line ends with an I, then read the next line, if that line contains a colour 39, then I would like to save the whole block of text to another file. If these two conditions aren't met, I dont want to save my values to the new text file.
Before anything about saving my values in classes are mentioned, these blocks of text can vary in size and values, so I dont always have a set range of values which is why i need to skip to the blank line
IO.File.WriteAllText("C:\Users\test2.txt", "") 'write to new file
Dim sKey As String
Dim sValue As Integer
For Each filterLine As String In File.ReadLines("C:\Users\test.txt")
sKey = Split(filterLine, ":")(0)
sValue = Split(filterLine, ":")(1)
If Not sValue.EndsWith("I") Then
ElseIf sValue.EndsWith("I") Then
End If
Next
Another method, using File.ReadLines to read lines of text from file. This method doesn't load all the text in memory, it reads from disc single lines of text, so it can also be useful when dealing with big files.
You could loop the IEnumerable collection it returns, but also use its GetEnumerator() method to control more directly when to move to the next line, or move more then one lines forward.
Its Enumerator.Current object returns the line of text currently read, Enumerator.MoveNext() moves to the next line.
A StringBuilder is used to store the strings when a match found. Strings are added to the StringBuilder object using its AppendLine() method.
This class is useful when dealing with strings that you need to store, compare and discard (or modify) quickly: since string are immutable, when you use String variables directly, especially in loops, you generate a whole lot of garbage that slows down any procedure quite a lot.
The blocks of text stored in the StringBuilder object are then written to a destination file using a StreamWriter with explicit encoding set to UTF-8 (writes the BOM). Its methods include asynchronous versions: WriteLine() can be replaced by awaitWriteLineAsync() to allow an async procedure.
Imports System.IO
Imports System.Text
Dim sourceFilePath = "<Path of the source file>"
Dim resultsFilePath = "<Path of the destination file>"
Dim sb As New StringBuilder()
Dim enumerator = File.ReadLines(sourceFilePath).GetEnumerator()
Using sWriter As New StreamWriter(resultsFilePath, False, Encoding.UTF8)
While enumerator.MoveNext()
If enumerator.Current.EndsWith("I") Then
sb.AppendLine(enumerator.Current)
enumerator.MoveNext()
If enumerator.Current.EndsWith("39") Then
While Not String.IsNullOrWhiteSpace(enumerator.Current)
sb.AppendLine(enumerator.Current)
enumerator.MoveNext()
End While
sWriter.WriteLine(sb.ToString())
End If
sb.Clear()
End If
End While
End Using
This will work:
Dim strFile As String = "c:\Test5\Source.txt"
Dim strOutFile As String = "c:\Test5\OutPut.txt"
Dim strOutData As String = ""
Dim SourceGroups As String() = Split(File.ReadAllText(strFile), vbCrLf + vbCrLf)
For Each sGroup As String In SourceGroups
Dim OneGroup() As String = Split(sGroup, vbCrLf)
If Strings.Right(OneGroup(0), 1) = "I" And (Strings.Right(OneGroup(1), 2) = "39") Then
If strOutData <> "" Then strOutData += (vbCrLf & vbCrLf)
strOutData += sGroup
End If
Next
File.WriteAllText(strOutFile, strOutData)
Something like this should work:
Dim base, i, c as Integer
Dim lines1$() = File.ReadLines("C:\Users\test.txt")
c = lines1.count
While i < c
if Len(RTrim(lines1(i))) Then
If Strings.Right(RTrim(lines1(i)), 1)="I" Then
base = i
i += 1
If Strings.Right(RTrim(lines1(i)), 2)="39" Then
While Len(RTrim(lines1(i))) 'skip to the next blank
i += 1
End While
' write lines1(from base to (i-1)) here
Else
While Len(RTrim(lines1(i)))
i += 1
End While
End If
Else
i += 1
End If
Else
i += 1
End If
End While

Renaming all files in a folder

I'm wondering if it's possible to rename all the files in a folder with a simple program, using vb.NET
I'm quite green and not sure if this is even possible.
Lets say there is a folder containing the files:
Text_Space_aliens.txt, fishing_and_hunting_racoons.txt and mapple.txt.
Using a few credentials:
Dim outPut as String = "TextFile_"
Dim fileType as String = ".txt"
Dim numberOfFiles = My.Computer.FileSystem.GetFiles(LocationFolder.Text)
Dim filesTotal As Integer = CStr(numberOfFiles.Count)
Will it be possible to rename these, regardless of previous name, example:
TextFile_1.txt, TextFile_2.txt & TextFile_3.txt
in one operation?
I think this should do the trick. Use Directory.GetFiles(..) to look for specific files. Enumerate results with a for..each and move (aka rename) files to new name. You will have to adjust sourcePath and searchPattern to work for you.
Private Sub renameFilesInFolder()
Dim sourcePath As String = "e:\temp\demo"
Dim searchPattern As String = "*.txt"
Dim i As Integer = 0
For Each fileName As String In Directory.GetFiles(sourcePath, searchPattern, SearchOption.AllDirectories)
File.Move(Path.Combine(sourcePath, fileName), Path.Combine(sourcePath, "txtFile_" & i & ".txt"))
i += 1
Next
End Sub
In your title you state something about chronologically, but within your question you never mentioned it again. So I did another example ordering files by creationTime.
Private Sub renameFilesInFolderChronologically()
Dim sourcePath As String = "e:\temp\demo"
Dim searchPattern As String = "*.txt"
Dim curDir As New DirectoryInfo(sourcePath)
Dim i As Integer = 0
For Each fi As FileInfo In curDir.GetFiles(searchPattern).OrderBy(Function(num) num.CreationTime)
File.Move(fi.FullName, Path.Combine(fi.Directory.FullName, "txtFile_" & i & ".txt"))
i += 1
Next
End Sub
I've never done Lambdas in VB.net but tested my code and it worked as intended. If anything goes wrong please let me know.

VBNET Reading a specific column on a line in a text file

I have saved written a text file and it currently reads:
"first","surname","pass"
I want to read the password column so the 3rd one and define that as a variable. Its basically for a login, if pass in text file matches the entered pass (from user).
I have searched for about an hour now and no luck. Could someone guide me to a correct path.
Thanks.
Simple example of reading a small file line by line and splitting each one into fields:
' get the values from the user somehow:
Dim first As String = "James"
Dim surname As String = "Bond"
Dim pass As String = "007"
Dim validated As Boolean = False ' assume wrong until proven otherwise
' check the file:
Dim fileName As String = "c:\some folder\path\somefile.txt"
Dim lines As New List(Of String)(System.IO.File.ReadAllLines(fileName))
For Each line As String In lines
Dim values() As String = line.Split(",")
If values.Length = 3 Then
If values(0).Trim(Chr(34)) = first AndAlso
values(1).Trim(Chr(34)) = surname AndAlso
values(2).Trim(Chr(34)) = pass Then
validated = True
Exit For
End If
End If
Next
' check the result
If validated Then
MessageBox.Show("Login Successful!")
Else
MessageBox.Show("Login Failed!")
End If
If this is a CSV file, as seems to be the case, then the easiest way to read it will be with the TextFieldParser class. The MSDN already provides an excellent example for how to use it to read a CSV file, so I won't bother reproducing it here.

Delete multiple files

I'm trying to delete multiple files in same folder with vb.net, but I haven't succeed yet. Help please?
I tried
Dim FileToDelete1 As String
Dim FileToDelete2 As String
Dim FileToDelete3 As String
Dim FileToDelete4 As String
Dim FileToDelete5 As String
FileToDelete1 = Application.StartupPath & "\1.exe"
FileToDelete2 = Application.StartupPath & "\2.dll"
FileToDelete3 = Application.StartupPath & "\3.dll"
FileToDelete4 = Application.StartupPath & "\4.dll"
FileToDelete5 = Application.StartupPath & "\5.dll"
If System.IO.File.Exists( FileToDelete1 ) = True Then
My.Computer.FileSystem.DeleteFile( FileToDelete1 )
ElseIf System.IO.File.Exists( FileToDelete2 ) = True Then
My.Computer.FileSystem.DeleteFile( FileToDelete2 )
ElseIf System.IO.File.Exists( FileToDelete3 ) = True Then
My.Computer.FileSystem.DeleteFile( FileToDelete3 )
ElseIf System.IO.File.Exists( FileToDelete4 ) = True Then
My.Computer.FileSystem.DeleteFile( FileToDelete4 )
ElseIf System.IO.File.Exists( FileToDelete5 ) = True Then
My.Computer.FileSystem.DeleteFile( FileToDelete5 )
End If
Several problems here.
First, File.Exists returns a Boolean value.
The "=True" is unnecessary because you're basically asking if True=True. Fortunately, it is.
Second, file existence or not it's not the only way to fail. For instance, if the file is in use, you'll get an exception. You should handle it.
Third, what if you need to delete a thousand files? Would you create a String for each one of them? There are better options, for instance, the GetFiles method which will return a ReadOnly List of Strings, each one representing one file.
I don't know your needs, but to catch the files you mention, the following call can be made:
FileIO.FileSystem.GetFiles(Application.StartupPath, FileIO.SearchOption.SearchTopLevelOnly, {"?.exe", "?.dll"})
It will get every EXE and DLL file if it's name consists in only one character.
Finally, notice that if the first condition is met, no other will be evaluated, hence no other file will be deleted.
With that implementation you'll need to run the program 5 times in order to delete every file.
GetFiles method solves this as well.
Additionally, consider importing namespaces so you don't need to prefix them in every method call.
Looks like you want to do some thing like this
Dim fileNames() as string={"1","2","3"}
Dim fileTypes() as string={"exe","dll"}
directory.SetCurrentDirectory(Application.StartupPath)
For each fileName as string in fileNames
For each fileType as string in fileTypes
if My.Computer.FileSystem .FileExists (fileName &"."& fileType) then
try
My.Computer.FileSystem.DeleteFile( fileName &"."& fileType )
catch ex As Exception
'**** processings related with exception.
end try
endif
'Dim files() As String = Directory.GetFiles(dirPath, fileName &"." & fileType, SearchOption.AllDirectories)
'For Each FileToDelete as string in files
' My.Computer.FileSystem.DeleteFile( FileToDelete )
'Next
Next
Next