I have 'N' number of files in a folder, the file names follows some common procedure(file0....fileN). the file names looks like:
file1.pdf
..
file7.pdf
..
file10.pdf
..
file15.pdf
..
fileN.pdf
Am collecting these files into a list of string using the following code:
Dim Files As String() = Directory.GetFiles(folderBase + "\files", "*.pdf")
here what is the problem am facing is that am getting in the list in the following order:
file1.pdf
file10.pdf
..
file2.pdf
..
file15.pdf
..
fileN.pdf
Getting file10.pdf after file1.pdf. i want to get file names in the sequential order(file1.pdf,file2.pdf...etc)
i have tried this also but it will not solve my problem:
Dim Files As List(Of String) = Directory.GetFiles(folderBase + "\files", "*.pdf").OrderBy(Function(f) New FileInfo(f).Name).ToList()
If you need to use an array then sort function can be used
Dim Files As String() = Directory.GetFiles(folderBase + "\files", "*.pdf")
System.Array.Sort(Of String)(Files)
Here is an approach that uses sorted dictionary. It assumes that the file names are letters followed by number(s). This works by making the file names the same length and using that as the key for the sorted dictionary.
'get the file name only
Dim fnames As IEnumerable(Of String) = From f In Files
Select IO.Path.GetFileNameWithoutExtension(f)
'get the longest file name
Dim max As Integer = fnames.Max(Function(fs) fs.Length)
'a palce for the results
Dim sd As New SortedDictionary(Of String, String)
Dim nums() As Char = "0123456789".ToCharArray
'create dictionary entries.
For ix As Integer = 0 To fnames.Count - 1
Dim fn As String = fnames(ix)
Dim idx As Integer = fn.IndexOfAny(nums)
If idx >= 0 Then fn = fn.Insert(idx, New String(" "c, max - fn.Length))
sd.Add(fn, Files(ix))
Next
Dim l As List(Of String) = sd.Values.Select(Function(f) IO.Path.GetFileName(f)).ToList
When working with paths use the methods in IO.Path, e.g.
Dim Files As String() = IO.Directory.GetFiles(IO.Path.Combine(folderBase, "files"), "*.pdf")
One other thing, use & for concatenation of strings not +.
Related
I'm developing a code that extracts the directories names.
The objective is to save the last 2 digits of each folder into a array.
The problem is that it's not possible to convert (directly) to a string array
How do i solve this?
Below is what i got so far
Dim di As New IO.DirectoryInfo(path)
Dim a As Integer = Drs.Length
Dim Drs() As IO.DirectoryInfo = di.GetDirectories()
Dim Run As String()
For n = 1 To a
Run = Mid(Drs(n), Len(Drs(n)) - 2, 2)
Next
Best Regards
A
The last two digits or characters of each folder-name? If the latter ...
Dim Run As String() = Drs.Select(Function(d) d.Name.Substring(d.Name.Length - 2)).ToArray()
This obviously fails with a directory which name is shorter than 2 characters.
I want to know if it is possible to compute the name of a variable in VB.net. I need to open a bunch of text files at runtime. The exact number will be variable. I wanted to do something along the lines of:
For j = 1 to Filecount
Dim Filename As String = "File"&j
Dim File & j As New System.IO.StreamWriter(Filename)
Next
When I tried this, VB.net said it didn't like it. Is this possible?
I think you would be better off using a dictionary, which would allow you to get back to the appropriate stream writer using the filename later:
Dim fileDictoinary As New Dictionary(Of String, System.IO.StreamWriter)
For j = 1 To Filecount
Dim Filename As String = "File" & j
fileDictoinary.Add(Filename, New System.IO.StreamWriter(Filename))
Next
Then at a later time you can access the streamwriter using the filename in the dictionary:
Dim file4StreamWriter = fileDictoinary("File4")
file4StreamWriter.Write(True)
Currently the line of code looks like this:
Dim files() As String = System.IO.Directory.GetFiles(path, filehead & ".*.*.fsi")
Dim seqfsi() As Integer
ReDim seqfsi(files.GetUpperBound(0))
Dim args() As String
Dim file As String = ""
For Each file In files
args = Split(file, ".")
If args.Length = 4 Then
seqfsi(System.Array.IndexOf(files, file)) = CInt(args(args.GetUpperBound(0) - 1))
End If
The problem is, sometimes, in my case, the path looks something like:
C:\Users\c.brummett\Downloads
and the split causes a split in the username. How can I avoid this problem but still split by periods? I'm sorry I don't how to make this more relatable.
My idea was to use a DirectoryInfo and do something like:
Dim di As DirectoryInfo
di = New DirectoryInfo(path)
Dim files() As String = di.GetFiles(filehead & ".*.*.fsi")
Edit: The problem with this second bit of code, is that it returns the error
Value of type '1-dimensional array of System.IO.FileInfo' cannot be converted to '1-> dimensional array of String' because 'System.IO.FileInfo' is not derived from 'String'.`
You can forget about getting an array of file names (you don't need that anyway) and iterate on the array of FileInfo:
Dim files() As FileInfo = New DirectoryInfo(path).GetFiles(filehead & ".*.*.fsi")
Dim seqfsi() As Integer
ReDim seqfsi(files.GetUpperBound(0))
Dim args() As String
For Each file As FileInfo In files
args = Split(file.Name, ".")
If args.Length = 4 Then
seqfsi(System.Array.IndexOf(files, file)) = CInt(args(args.GetUpperBound(0) - 1))
End If
Note AllDirectories and change in the line doing the splitting. I didn't look at your array structure stuff.
Dim files() As String = System.IO.Directory.GetFiles("C:\temp", "*.doc", IO.SearchOption.AllDirectories)
Dim seqfsi() As Integer
ReDim seqfsi(files.GetUpperBound(0))
Dim args() As String
Dim file As String = ""
For Each file In files
args = file.Substring(file.LastIndexOf("\") + 1).Split(".")
If args.Length = 4 Then
seqfsi(System.Array.IndexOf(files, file)) = CInt(args(args.GetUpperBound(0) - 1))
End If
Next file
I have string say "c:\debug\ *.txt"
In Debug folder there are severeal .txt files , say test1.txt test2.txt test3.txt .
How can I get from this string c:\debug\ *.txt an array of wildcard files?
a(0)=c:\debug\test1.txt
a(1)=c:\debug\test2.txt
a(2)=c:\debug\test3.txt
It is also possible that the string would be something like "C:\logs\12*\ *.log"
a(0)=C:\logs\120114\01.log
a(0)=C:\logs\120114\02.log
a(0)=C:\logs\120114\03.log
etc.
Anyone have any ideas on this?
I use the following code:
Dim Path As String = "C:\debug"
Dim Dir As New DirectoryInfo(Path)
Dim q = (From x In Dir.GetFiles("*.txt", SearchOption.AllDirectories) Select x.FullName).ToArray
You might need to
Import System.IO
Import System.Linq
Basically your key for the requirement is SearchOption.AllDirectories which iterates through sub directories as well.
This should do it for you. It'll handle wildcards in directory part and filename part
Private Function GetFiles(ByVal Path As String) As List(Of String)
Dim drivePart As String, dirPart As String, filePart As String
drivePart = Path.Substring(0, Path.IndexOf("\") + 1)
dirPart = Path.Substring(Path.IndexOf("\") + 1, Path.LastIndexOf("\") - Path.IndexOf("\") - 1)
filePart = Path.Substring(Path.LastIndexOf("\") + 1)
Dim directories As New List(Of String)
Dim files As New List(Of String)
'' Walk directory tree finding matches
'' This should handle wildcards in any part of the path
Dim currentIndex As Integer = 0
Dim directoryMatch As String() = dirPart.Split("\")
For Each directory As String In directoryMatch
WalkDirectories(drivePart, directories, directoryMatch, currentIndex)
currentIndex += 1
Next
For Each directory As String In directories
files.AddRange(System.IO.Directory.GetFiles(directory, filePart))
Next
Return files
End Function
Private Sub WalkDirectories(ByVal dirPart As String, ByVal directories As List(Of String), ByVal directoryMatch As String(), ByVal currentIndex As Integer)
If currentIndex = directoryMatch.Length Then Return
For Each d As String In System.IO.Directory.GetDirectories(dirPart, directoryMatch(currentIndex))
directories.Add(d)
WalkDirectories(System.IO.Path.Combine(dirPart, d), directories, directoryMatch, currentIndex + 1)
Next
End Sub
Edit: just noticed that it wont handle UNC paths but it should be pretty easy to modify for that if you need to
Editted again to handle multiple directory levels and wildcards at multiple levels (eg C:\debug\12*\log1*\errors*.txt
Use the GetFiles from My.Computer.System and the ReadOnlyCollection(of String) from the system.collections.objectModel import and a searchoption as desired (top or all)
sPath = "C:\debug" ' your desired path
sFile1 = "t*.txt" ' your desired search pattern with * wildcard
sFile2 = "test?.txt" ' your desired search pattern with ? wildcard
dim lstFiles as system.collections.ObjectModel.ReadOnlyCollection(of String) = My.Computer.Filesystem.GetFiles(sPath, FileIO.SearchOption.SearchTopLevelOnly, sFile1)
'lstfiles contains all the files that match your selection
'if you really need an array you can convert the list to array here
dim i as integer = 0
for each sFile as string in lstfiles
a(i)=sfile
i+=1
next
You could use the 'Like' keyword:
' For your example, call this function with root = "C:\logs" and wild = "12*\*.log"
Friend Function GetMyFiles(root As String, wild As String, Optional allowsub As Boolean = True) As List(Of String)
Dim a As New List(Of String), pattern As String
' ensure root ends with a \
If Not root.EndsWith("\") Then root &= "\"
' the extra * allows for subdirectories in between, if required
pattern = root & If(allowsub, "*", "") & wild
For Each f As String In My.Computer.FileSystem.GetFiles(root, FileIO.SearchOption.SearchAllSubDirectories)
If f Like pattern Then a.Add(f)
Next
Return a
End Function
Of course, if you hit a protected system directory, it'll fail.
This function is just to demonstrate the 'Like' keyword.
It will work if 'root' isn't a drive root (e.g. C:).
Done properly, a separate function would collect directories first, each tested for access permissions in a Try/Catch block. Here's how that looks:
Friend Function GetAllAccessibleDirs(ByRef Dir As String, Optional inclDir As Boolean = True, Optional Sort As Boolean = False) As List(Of String)
Dim D As New List(Of String), Q As New Queue(Of String), dummy As DirectoryInfo, s As String
If inclDir Then D.Add(Dir)
Q.Enqueue(Dir)
While Q.Count
For Each s In GetTopLevelDirs(Q.Dequeue)
Try
dummy = My.Computer.FileSystem.GetDirectoryInfo(s)
D.Add(s)
Q.Enqueue(s)
Catch
' Inaccessible folder
End Try
Next
End While
If Sort AndAlso D.Count Then D.Sort()
Return D
End Function
Friend Function GetTopLevelDirs(ByRef dir As String) As List(Of String)
Try
Return My.Computer.FileSystem.GetDirectories(dir, FileIO.SearchOption.SearchTopLevelOnly).ToList
Catch
Return New List(Of String)
End Try
End Function
I have a string like
Query_1,ab563372363_C/R,100.00,249,0,0,1,249,1,249,1e-132, 460
Query_1,ab563372356_C/R,99.60,249,1,0,1,249,1,249,5e-131, 455
in a file
in two separate lines. I am reading it from the textbox. I have to output ab563372363_C/R and ab563372356_C/R in a text box. I am trying to use the split function for that but its not working..
Dim splitString as Array
results = "test.txt"
Dim FileText As String = IO.File.ReadAllText(results) 'reads the above contents from file
splitString = Split(FileText, ",", 14)
TextBox2.text = splitString(1) & splitString(13)
for the above code, it just prints the whole thing.. What's wrong?
Try this
Private Function GetRequiredText() As List(Of String)
Dim requiredStringList As New List(Of String)
Dim file = "test.txt"
If FileIO.FileSystem.FileExists(file) Then
Dim reader As System.IO.StreamReader = System.IO.File.OpenText(file)
Dim line As String = reader.ReadLine()
While line IsNot Nothing
requiredStringList.Add(line.Split(",")(1))
line = reader.ReadLine()
End While
reader.Close()
reader.Dispose()
End If
Return requiredStringList
End Function
This will read the file line by line and add the item you require to a list of strings which will be returned by the function.
Returning a List(Of String) may be overkill, but it's quite simple to illustrate and to work with.
You can then iterate through the list and do what you need with the contents of the list.
Comments welcome!!
Also this might work...
Dim query = From lines In System.IO.File.ReadAllLines(file) _
Select lines.Split(",")(1)
this will return an IEnumerable(Of String)
Enjoy
First
Since you are reading the whole text, your FileText would be ending like this:
Query_1,ab563372363_C/R,100.00,249,0,0,1,249,1,249,1e-132,460
\r\n
Query_1,ab563372356_C/R,99.60,249,1,0,1,249,1,249,5e-131, 455
So when you are referencing to your splitStringwith those indexes (1, 13) your result might probably be wrong.
Second
Try to specify what kind of type your array is, Dim splitString as Array should be Dim splitString As String()
Third
Make your code more readable/maintainable and easy to edit (not only for you, but others)
The Code
Private const FirstIndex = 1
Private const SecondIndex = 12
Sub Main
Dim myDelimiter As Char
Dim myString As String
Dim mySplit As String()
Dim myResult1 As String
Dim myResult2 As String
myDelimiter = ","
myString += "Query_1,ab563372363_C/R,100.00,249,0,0,1,249,1,249,1e-132, 460"
myString += "Query_1,ab563372356_C/R,99.60,249,1,0,1,249,1,249,5e-131, 455"
mySplit = myString.Split(myDelimiter)
myResult1 = mySplit(FirstIndex)
myResult2 = mySplit(SecondIndex)
Console.WriteLine(myResult1)
Console.WriteLine(myResult2)
End Sub