我是VB.net的新手,我需要帮助。
我想要做的是从两个特定行之间的文本文件中读取行。在这些行中,我必须寻找一个特定的行并显示下一行,如果这有意义的话。问题在于,有多对这些标记线包含我需要的确切线条。我希望你的解释很清楚!这可能吗?
我正在寻找屏幕截图中显示的文本文件部分中的数字10下面的行。由于该文件中有很多10个,我需要在部件上读取它以获得所需的确切行。
以下代码是我迄今为止感谢@TimSchmelter的前一个问题http://www.dotnetcurry.com/windows-azure/1166/aspnet-mvc-multiple-adfs-owin-katana。这实际上是寻找特定行并显示下一行的位,但它会读取该文本文件中的所有行。
Dim x1 As Decimal = File.ReadLines("filepath").
SkipWhile(Function(line) Not line.Contains(" 10")).Skip(1).FirstOrDefault()
If x1 >= 0.0 Then TextBox1.Text = x1
答案 0 :(得分:0)
您的原始代码是最好的,因为它可以让您更好地控制您阅读的内容和诸如此类的内容,因此我将在我的回答中使用它。
LINQ方法只会为您提供所需内容的第一个实例,因此最好逐行读取整个文件。
首先,保持一条坐标的结构:
Public Structure Line
Public Start As PointF 'Start coordinates.
Public [End] As PointF 'End coordinates.
Public Sub New(ByVal Start As PointF, ByVal [End] As PointF)
Me.Start = Start
Me.End = [End]
End Sub
Public Sub New(ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single)
Me.New(New PointF(x1, y1), New PointF(x2, y2))
End Sub
End Structure
我们将使用此结构,以便我们可以返回我们找到的所有行的列表。
这将逐行读取文件并查找我们想要的值:
编辑:我已更新代码以使其正确读取坐标(即不再受订单约束:10,20,11,21)。
我还让它只读取位于
AcDbLine/LINE
块内的坐标。
Public Function ParseLines(ByVal File As String) As List(Of Line)
'Create a list of Line structures.
Dim Lines As New List(Of Line)
'Create an array holding four items: the coordinates for 10, 20, 11 and 21.
Dim CoordValues As Single() = New Single(4 - 1) {}
'Declare a variable holding the current index in the array:
'CoordIndex = 0 represents the first X-coordinate (10).
'CoordIndex = 1 represents the first Y-coordinate (20).
'CoordIndex = 2 represents the second X-coordinate (11).
'CoordIndex = 3 represents the second Y-coordinate (21).
Dim CoordIndex As Integer = 0
'Declare a variable indicating whether we are currently inside an AcDbLine/LINE block.
Dim InsideAcDbLine As Boolean = False
Using sReader As New StreamReader(File) 'Open a StreamReader to our file.
While Not sReader.EndOfStream 'Keep reading until we've reached the end of the file.
Dim line As String = sReader.ReadLine() 'Read a line.
'Check if we're inside a AcDbLine/LINE block and that we aren't at the end of the file.
If InsideAcDbLine = True AndAlso Not sReader.EndOfStream Then
'Determine if the current line contains 10, 20, 11 or 21.
'Depending on what "line.Trim()" returns it will execute the code of the respective "Case".
'Ex: If "line.Trim()" returns "20" it will execute the code of 'Case "20"', which is 'CoordIndex = 1'.
Select Case line.Trim() 'Trim() removes leading or trailing space characters from the string (i.e. " 10" -> "10").
Case "10" : CoordIndex = 0 'We've reached "10", the following line is coordinate x1.
Case "20" : CoordIndex = 1 'We've reached "20", the following line is coordinate y1.
Case "11" : CoordIndex = 2 '[...] x2.
Case "21" : CoordIndex = 3 '[...] y2.
Case Else : Continue While
' "Continue While" stops execution at this point and
' goes back to the beginning of the loop to: "Dim line As String = ...".
'
' - If "line.Trim()" DOES NOT return 10, 20, 11 or 21 then we
' just want to skip the rest of the code (in other words: ignore the current line).
End Select
'I used colons above for better readability as they can be used to replace line breaks.
'For example the above SHOULD ACTUALLY be:
'
'Select Case line.Trim()
' Case "10"
' CoordIndex = 0
' Case "11"
' (and so on)
'=========================================
Dim nextLine As String = sReader.ReadLine() 'Read the next line.
Dim Coordinate As Single 'Declare a variable for the current coordinate.
'Try parsing the line into a single using
'invariant culture settings (decimal points must be dots: '.').
If Single.TryParse(nextLine.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, Coordinate) = True Then
CoordValues(CoordIndex) = Coordinate 'Add the coordinate to the array.
If CoordIndex = CoordValues.Length - 1 Then 'Have we reached the end of the array?
InsideAcDbLine = False 'We've found all values we want. Do not look for any more in this block.
Lines.Add(New Line(CoordValues(0), CoordValues(1), CoordValues(2), CoordValues(3))) 'Create a new Line and set its coordinates to the values of 10, 20, 11 and 21.
Array.Clear(CoordValues, 0, CoordValues.Length) 'Set all the items in the array to zero.
End If
End If
End If
'Check if we've reached an "AcDbLine" or "LINE" marker.
'Used in order to determine whether we are inside a AcDbLine/LINE block.
'If we aren't, then we shouldn't look for any coordinates.
Select Case line.Trim()
Case "AcDbLine" : InsideAcDbLine = True 'Start of an AcDbLine/LINE block.
Case "LINE" : InsideAcDbLine = False 'End of an AcDbLine/LINE block.
End Select
End While
End Using
Return Lines 'Return our list of lines.
End Function
此代码只有在找到四个不同的坐标后才会向列表中添加一个新行,即如果它最后只找到x1,y1和x2(但不是y2),它将忽略这些值。
以下是如何使用它:
Dim Lines As List(Of Line) = ParseLines("filepath")
'Iterate through every parsed line.
For Each Line As Line In Lines
'Print all parsed lines to console in the format of:
'Line start: {X=x1, Y=y1}
'Line end: {X=x2, Y=y2}
Console.WriteLine("Line start: " & Line.Start.ToString())
Console.WriteLine("Line end: " & Line.End.ToString())
Console.WriteLine()
Next
要获得您可以执行的行的单独坐标(假设您仍在使用上面的循环):
Dim StartX As Single = Line.Start.X
Dim StartY As Single = Line.Start.Y
Dim EndX As Single = Line.End.X
Dim EndY As Single = Line.End.Y
如果您想要在没有循环的情况下访问各个行,您可以这样做:
Dim Line As Line = Lines(0) '0 is the first found line, 1 is the second (and so on).
<强>文档强>