Generate multiple files in a loop using visual basic - vb.net

I am new to Visual Basic.
I wonder if I wanna generate multiple files in a while loop. It seems that the FILESTREAM cannot be reused even I set it into nothing at the end of loop.
Dim fs as FILESTREAM = nothing
Dim i as integer = 0
Dim path as string = "c:\users\...\Desktop\"
Dim name as string = nothing
while i<10
name = path + i.tostring
fs=File.Create(name)
i+=1
fs=nothing
end while
Thank you very much!

It's not clear if you're using the FileStream just to create a blank file or if you're planning on performing other operations against the new files. If you're just trying to create empty files and manipulate them later, after creation, then this should work:
Sub Main()
Dim i As Integer = 0
' You can use properties of My.Computer to find the current user's Desktop
Dim path As String = My.Computer.FileSystem.SpecialDirectories.Desktop
Dim fileName As String = String.Empty
While i < 10
fileName = path & "\" & i.ToString
System.IO.File.Create(fileName)
i += 1
End While
End Sub

Related

get full string before first second third etc. split

I have a file location and I need to check if it exists.
The way I wan't to do it is like this:
Dim route As String = ("C:\testing1\testing2\testing3\testing4\testing5\TEXTBESTAND.txt")
If System.IO.File.Exists(route) Then
MsgBox("BESTAAT HET WERKT!")
Else
Dim subroute() As String = route.Split("\"c)
Dim counting As Integer = route.Split("\"c).Length - 1
For count2 As Integer = 0 To counting - 1
Dim firstbackslash As Integer = route.IndexOf("\")
Dim backslash As Integer = route.IndexOf("\", firstbackslash + 1)
Dim firstPart As String = route.Substring(0, backslash)
MsgBox(firstPart)
Next
What I try to accomplisch is that I fist check if folder "C:" exists then "C:\testing1" then "C:\testing1\testing2" etc.
But I cant find something like this on the internet nor with some messing around...
Here is an algorithm that that will give you all the paths starting from the root and building up to the final path including the filename. You can use this to check for each folder and create them as you go if they don't exist:
Sub Main()
Dim route As String = ("C:\testing1\testing2\testing3\testing4\testing5\TEXTBESTAND.txt")
Dim fi As New System.IO.FileInfo(route)
If Not fi.Exists Then
Dim fileName As String = Path.GetFileName(route)
Dim di As DirectoryInfo = fi.Directory
Dim pathStack As New Stack(Of String)()
pathStack.Push(di.Name)
While Not IsNothing(di.Parent)
di = di.Parent
pathStack.Push(di.Name)
End While
Dim curPath As String = ""
While pathStack.Count > 0
curPath = Path.Combine(curPath, pathStack.Pop)
' ... do something with "curPath" in here ...
' ... like check for existence and create it ...
Console.WriteLine(curPath)
End While
curPath = Path.Combine(curPath, fileName)
' ... do something with "curPath" in here ...
' ... this is the full path including the file on the end ...
Console.WriteLine(curPath)
End If
Console.Write("Press Enter to quit...")
Console.ReadLine()
End Sub
Output:
C:\
C:\testing1
C:\testing1\testing2
C:\testing1\testing2\testing3
C:\testing1\testing2\testing3\testing4
C:\testing1\testing2\testing3\testing4\testing5
C:\testing1\testing2\testing3\testing4\testing5\TEXTBESTAND.txt
Press Enter to quit...
Don't use string mnaipulation to work with file or folder paths. use the Path class.
One option:
Private Function GetExistingSubPath(fullPath As String) As String
If Directory.Exists(fullPath) OrElse File.Exists(fullPath) Then
Return fullPath
End If
Dim subPath = Path.GetDirectoryName(fullPath)
If subPath Is Nothing Then
Return Nothing
End If
Return GetExistingSubPath(subPath)
End Function
Sample usage:
Dim fullPath = "C:\testing1\testing2\testing3\testing4\testing5\TEXTBESTAND.txt"
Dim existingSubPath = GetExistingSubPath(fullPath)
Console.WriteLine(existingSubPath)
What I try to accomplisch is that I fist check if folder "C:" exists then "C:\testing1" then "C:\testing1\testing2" etc.
Noooooooooooo!
That's not how to do it at all! The file system is volatile: things can change between each of those checks. Moreover, file existence is only one of many things that can stop file access.
It's much better practice to try to access the file in question, and then handle the exception if it fails. Remember, because of the prior paragraph you have to be able to handle exceptions here anyway. .Exists() doesn't save you from writing that code. And each check is another round of disk access, which is about the slowest thing it's possible to do in a computer... even slower than unrolling the stack for an exception, which is the usual objection to this idea.
I fixed it, know I can check if multiple text files are at the locations I need, if there not I place the Textfiles at the location I need them. Then I can add something in it. (I need to put a Location of something else in it.)
Dim een As String = "C:\testing1\testing2\testing7\testing1\testing1\text.txt"
Dim twee As String = "C:\testing1\testing2\testing7\testing2\testing1\text.txt"
Dim drie As String = "C:\testing1\testing2\testing7\testing3\testing1\text.txt"
Dim vier As String = "C:\testing1\testing2\testing7\testing4\testing1\text.txt"
Dim Files As String() = {een, twee, drie, vier}
For Each route As String In Files
If System.IO.File.Exists(route) Then
MsgBox("BESTAAT HET WERKT!")
Else
Dim subroute() As String = route.Split("\"c)
Dim counting As Integer = route.Split("\"c).Length - 1
Dim tel As Integer = route.Substring(route.LastIndexOf("\") + 1).Count
Dim bestandnaam As String = route.Substring(route.LastIndexOf("\") + 1)
For count2 As Integer = 0 To route.Length - tel - 1
Dim firstbackslash As Integer = route.IndexOf("\", count2)
Dim backslash As Integer = route.IndexOf("\", count2)
Dim Mapnaam As String = route.Substring(0, backslash)
count2 = firstbackslash
If System.IO.Directory.Exists(Mapnaam) Then
Else
System.IO.Directory.CreateDirectory(Mapnaam)
End If
Next
If System.IO.File.Exists(route) Then
Else
Dim objStreamWriter As System.IO.StreamWriter
objStreamWriter = New System.IO.StreamWriter(route)
Dim label As String
Select Case route
Case een
label = "een"
Case twee
label = "twee"
Case drie
label = "drie"
Case vier
label = "vier"
End Select
Dim value As String = InputBox("Route invullen naar " & label)
'Dim objStreamWriter As New System.IO.StreamWriter(route)
objStreamWriter.Write(value)
objStreamWriter.Close()
'Using sw As System.IO.StreamWriter = System.IO.File.AppendText(route)
' sw.WriteLine(value)
'End Using
End If
End If
Next route

Parse String to Date from a filename variable

Purpose is to move files in their specified folders, from which they were in IF the date is at least a day old from today. I'm having some trouble moving the file since I don't see it archived. I'm assuming it's parsing the date from a filename. VS2005 .Net 2.0
Sub CopytoArchive(ByVal mydirpath)
'mydirpath = "C:\UTResults\"
'T:\UTResults\Press3\sv70206655\data07012015.txt is an example of txtFileList
Dim txtFileList As String() = Directory.GetFiles(mydirpath, "*.txt", SearchOption.AllDirectories) 'Search all files in the given path with .txt type
For Each txtName As String In txtFileList
Dim pressname As String = txtName.Substring(0, txtName.LastIndexOf("\")) 'take out the file extension
pressname = pressname.Substring(0, pressname.LastIndexOf("\")) 'take out the folder after the press folder for a clean "PRESS" look
pressname = pressname.Remove(0, 13)
Dim folderexists As String = Path.Combine("C:\writetest\", pressname)
Dim filename = txtName.Remove(0, 4)
filename = filename.Substring(0, filename.LastIndexOf("."))
filename = Convert.ToDateTime(filename)
If filename < Date.Now Then
If My.Computer.FileSystem.DirectoryExists(folderexists) Then
My.Computer.FileSystem.MoveFile(txtName, folderexists)
Else
My.Computer.FileSystem.CreateDirectory(folderexists)
My.Computer.FileSystem.MoveFile(txtName, folderexists)
End If
End If
Next
End Sub
Sub CopytoArchive(ByVal mydirpath As String)
'mydirpath = "C:\UTResults\"
'T:\UTResults\Press3\sv70206655\data07012015.txt is an example of txtFileList
Dim dir As New DirectoryInfo(mydirpath)
Dim fileInfos = dir.EnumerateFiles("*.txt", SearchOption.AllDirectories)
fileInfos = fileInfos.
Where(Function(fi) DateTime.ParseExact(RegEx.Replace(fi.Name, "[^0-9]", ""), "MMddyyyy", Nothing) < DateTime.Now.AddDays(-1))
'The magic is here ------^^^
For Each info In fileInfos
Dim pressname As String = _
Path.GetDirectoryName(info.DirectoryName).Replace(mydirpath, "C:\writetest\")
'Better/more efficient to just call CreateDirectory() every time
My.Computer.FileSystem.CreateDirectory(pressname)
My.Computer.FileSystem.MoveFile(info.FullName, pressname)
Next
End Sub
Date strings are usually a problem, here is basic approach:
Dim s As String = "data07012015.txt"
s = s.Substring(4)
s = s.Substring(0, s.LastIndexOf("."))
' convert to valid en date string
s = s.Insert(2, "/").Insert(5, "/")
Dim dt As Date = s
If dt < Now.AddDays(-1) Then
Stop
Else
Stop
End If

Why is each String being written to a different file?

I am trying to generate a size-based list of files. The current size being passed is 10 MB worth of file-names per text file. Instead of it counting to 10 MB and then incrementing the version letter, it is writing each file-name to its own individual file. This is strange as each file is ~150 kb, but I cannot figure out why it is reporting total as > number every time the code loops.
Private Function GenerateListsForSize(source As String, destination As String, name As String, number As Integer)
Dim files As ArrayList = New ArrayList
Dim total As Integer
Dim version As Char = "A"
Dim path As String
Dim counter As Integer = 0
Dim passTexts As ArrayList = New ArrayList
Dim infoReader As System.IO.FileInfo
For Each foundFile As String In My.Computer.FileSystem.GetFiles(source)
files.Add(foundFile)
Next
If files.Count > 1 Then 'If files exist in dir, count them and get how many lists
path = destination & "\" & name & version & ".txt"
Dim fs As FileStream = File.Create(path) 'creates the first text file
fs.Close()
passTexts.Add(path)
For Each foundfile As String In files
Using sw As StreamWriter = New StreamWriter(path)
Console.WriteLine(foundfile)
sw.WriteLine(foundfile)
End Using
infoReader = My.Computer.FileSystem.GetFileInfo(foundfile)
total = total + infoReader.Length
If total >= number Then 'If max file size is reached
version = Chr(Asc(version) + 1) 'Increments Version
path = destination & "\" & name & version & ".txt" 'Corrects path
fs = File.Create(path) 'creates the new text file with updated path
fs.Close()
passTexts.Add(path)
total = 0 'resets total
End If
Next
End If
Return passTexts
End Function
Every time through the loop, you open the file (using the StreamWriter) which overwrites the previous contents. Your file will only ever have one filename inside it. Instead of opening and writing every time through the loop, only write the file when you have accumulated all the filenames. I removed the calls to File.Create as they aren't necessary. The StreamWriter will create the file if it doesn't exist. And I changed the ArrayList's to List(Of String) since they're easier to work with. Also, be sure to turn Option Strict On. This code has not been tested, but it should get my point across. I hope I haven't misunderstood what you were trying to do.
Private Function GenerateListsForSize(source As String, destination As String, name As String, number As Integer) As List(Of String)
Dim files As New List(Of String)()
Dim filenamesToWrite As New List(Of String)()
Dim total As Integer
Dim version As Char = "A"
Dim filename As String
Dim counter As Integer = 0
Dim passTexts As New List(Of String)()
Dim infoReader As System.IO.FileInfo
files.AddRange(My.Computer.FileSystem.GetFiles(source))
If files.Count > 1 Then 'If files exist in dir, count them and get how many lists
'Path.Combine is preferable to concatenating strings.
filename = Path.Combine(destination, String.Format("{0}{1}.txt", name, version))
passTexts.Add(filename)
For Each foundfile As String In files
filenamesToWrite.Add(foundfile)
infoReader = My.Computer.FileSystem.GetFileInfo(foundfile)
total = total + infoReader.Length
If total >= number Then 'If max file size is reached
'Only write when the list is complete for this batch.
Using sw As StreamWriter = New StreamWriter(filename)
For Each fname As String In filenamesToWrite
Console.WriteLine(foundfile)
sw.WriteLine(foundfile)
Next
End Using
version = Chr(Asc(version) + 1) 'Increments Version
filename = Path.Combine(destination, String.Format("{0}{1}.txt", name, version)) 'corrects path
passTexts.Add(filename) 'IS THIS A DUPLICATE????
total = 0 'resets total
filenamesToWrite.Clear() 'clear the list of file names to write
End If
Next
End If
Return passTexts
End Function

how to save file in desired path with StreamWriter

I am saving a .csv file in my directory by giving the path with StreamWriter. Now i want to give the option to user to save that file desired path. how can it. help me somebody.
Dim objStreamWriter = New IO.StreamWriter("c:\FaultTypesByMonth.csv")
Dim Str As String
Dim i As Integer
Dim j As Integer
Dim headertext1(rsTerms.Columns.Count) As String
Dim k As Integer = 0
Dim arrcols As String = Nothing
For Each column As DataColumn In TempTab.Columns
headertext1(k) = column.ColumnName
arrcols += column.ColumnName.ToString() + ","c
k += 1
Next
objStreamWriter.WriteLine(arrcols)
For i = 0 To (TempTab.Rows.Count - 1)
For j = 0 To (TempTab.Columns.Count - 1)
'this IF statement stops it from adding a comma after the last field
If j = (TempTab.Columns.Count - 1) Then
Str = (TempTab.Rows(i)(j).ToString)
Else
Str = (TempTab.Rows(i)(j).ToString & ",")
End If
objStreamWriter.Write(Str)
Next
objStreamWriter.WriteLine()
Next
objStreamWriter.Close()
' After save the file in C:/ I want to save the same file in any other Path for my convenience.
'------------------------------------------------------------------------------------------------
Dim sd As New SaveFileDialog
sd.Filter = "CSV Files (*.csv)|*.csv"
sd.FileName = "FaultTypesByMonth"
If sd.ShowDialog = Windows.Forms.DialogResult.OK Then
'save the file here
Debug.WriteLine("Save file location:" + sd.FileName)
End If
If it's a console application you could read a path argument from the command line.
If it's a GUI application you can show a save file dialog box, in WinForms use the SaveFileDialog class.
To save a file to different locations put the writer code in a function which takes the file path as an argument:
Sub SaveFile(filePath As String)
Dim objStreamWriter = New IO.StreamWriter(filePath)
' ... your code here
End Sub
Sub ButtonClick
SaveFile("c:\FaultTypesByMonth.csv")
' ... SaveFileDialog code
SaveFile(sd.Filename)
End Sub
To copy a file use File.Copy:
' ... SaveFileDialog code
File.Copy("c:\FaultTypesByMonth.csv", sd.Filename)
Use the SaveFileDialog class
Simple example:
Private Sub SaveFile()
Dim sd As New SaveFileDialog
sd.Filter = "CSV Files (*.csv)|*.csv"
If sd.ShowDialog = Windows.Forms.DialogResult.OK Then
'save the file here
Debug.WriteLine("Save file location:" + sd.FileName)
End If
End Sub

Search line in text file and return value from a set starting point vb.net

I'm currently using the following to read the contents of all text files in a directory into an array
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
Within the text files are only 6 lines that all follow the same format and will read something like
forecolour=black
I'm trying to then search for the word "forecolour" and retrieve the information after the "=" sign (black) so i can then populate the below code
AllDetail(numfiles).uPath = ' this needs to be the above result
I've only posted parts of the code but if it helps i can post the rest. I just need a little guidance if possible
Thanks
This is the full code
Dim numfiles As Integer
ReDim AllDetail(0 To 0)
numfiles = 0
lb1.Items.Clear()
Dim lynxin As New IO.DirectoryInfo(zMailbox)
lb1.Items.Clear()
For Each txtfi In lynxin.GetFiles("*.txt")
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
ReDim Preserve AllDetail(0 To numfiles)
AllDetail(numfiles).uPath = 'Needs to be populated
AllDetail(numfiles).uName = 'Needs to be populated
AllDetail(numfiles).uCode = 'Needs to be populated
AllDetail(numfiles).uOps = 'Needs to be populated
lb1.Items.Add(IO.Path.GetFileNameWithoutExtension(txtfi.Name))
numfiles = numfiles + 1
Next
End Sub
AllDetail(numfiles).uPath = Would be the actual file path
AllDetail(numfiles).uName = Would be the detail after “unitname=”
AllDetail(numfiles).uCode = Would be the detail after “unitcode=”
AllDetail(numfiles).uOps = Would be the detail after “operation=”
Within the text files that are being read there will be the following lines
Unitname=
Unitcode=
Operation=
Requirements=
Dateplanned=
For the purpose of this array I just need the unitname, unitcode & operation. Going forward I will need the dateplanned as when this is working I want to try and work out how to only display the information if the dateplanned matches the date from a datepicker. Hope that helps and any guidance or tips are gratefully received
If your file is not very big you could simply
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
For each line in allLines
Dim parts = line.Split("="c)
if parts.Length = 2 andalso parts(0) = "unitname" Then
AllDetails(numFiles).uName = parts(1)
Exit For
End If
Next
If you are absolutely sure of the format of your input file, you could also use Linq to remove the explict for each
Dim line = allLines.Where(Function(x) (x.StartsWith("unitname"))).SingleOrDefault()
if line IsNot Nothing then
AllDetails(numFiles).uName = line.Split("="c)(1)
End If
EDIT
Looking at the last details added to your question I think you could rewrite your code in this way, but still a critical piece of info is missing.
What kind of object is supposed to be stored in the array AllDetails?
I suppose you have a class named FileDetail as this
Public class FileDetail
Public Dim uName As String
Public Dim uCode As String
Public Dim uCode As String
End Class
....
numfiles = 0
lb1.Items.Clear()
Dim lynxin As New IO.DirectoryInfo(zMailbox)
' Get the FileInfo array here and dimension the array for the size required
Dim allfiles = lynxin.GetFiles("*.txt")
' The array should contains elements of a class that have the appropriate properties
Dim AllDetails(allfiles.Count) as FileDetail
lb1.Items.Clear()
For Each txtfi In allfiles)
Dim allLines() As String = File.ReadAllLines(txtfi.FullName)
AllDetails(numFiles) = new FileDetail()
AllDetails(numFiles).uPath = txtfi.FullName
Dim line = allLines.Where(Function(x) (x.StartsWith("unitname="))).SingleOrDefault()
if line IsNot Nothing then
AllDetails(numFiles).uName = line.Split("="c)(1)
End If
line = allLines.Where(Function(x) (x.StartsWith("unitcode="))).SingleOrDefault()
if line IsNot Nothing then
AllDetails(numFiles).uName = line.Split("="c)(1)
End If
line = allLines.Where(Function(x) (x.StartsWith("operation="))).SingleOrDefault()
if line IsNot Nothing then
AllDetails(numFiles).uOps = line.Split("="c)(1)
End If
lb1.Items.Add(IO.Path.GetFileNameWithoutExtension(txtfi.Name))
numfiles = numfiles + 1
Next
Keep in mind that this code could be really simplified if you start using a List(Of FileDetails)