Vb.net 如何使用Visual Basic从文本文件中获取点坐标?
我想从文本文件中获取点坐标。文本文件太长。你可以在下面找到一个样本 示例文本 点数据 美元 $$ --------------------------------------------------------------------------------$ $$组定义$ $$------------------------------------------------------------------------------$ 首先,我不擅长编码,如果你简单地告诉我,我将不胜感激 目的是获取点id和坐标Vb.net 如何使用Visual Basic从文本文件中获取点坐标?,vb.net,Vb.net,我想从文本文件中获取点坐标。文本文件太长。你可以在下面找到一个样本 示例文本 点数据 美元 $$ --------------------------------------------------------------------------------$ $$组定义$ $$------------------------------------------------------------------------------$ 首先,我不擅长编码,如果你简单地告诉我,我将不胜感激 目的是
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim myfilepath, test, test1, test2, i, strline
If OpenFileDialog1.ShowDialog = DialogResult.OK Then
myfilepath = OpenFileDialog1.FileName
End If
Dim cordx()
Dim cordy()
Dim cordz()
Dim satirlar = IO.File.ReadAllLines(myfilepath).Length
MsgBox(satirlar)
Dim lines = IO.File.ReadAllLines(myfilepath).ToList
For i = 0 To satirlar
If lines(i).ToLower.StartsWith("points") Then
cordx(i) = Mid(lines(i), 25, 33)
End If
Next
MsgBox(cordx)
End Sub
结束类让我们完成并简化代码:
'请将您的按钮称为比按钮1更好的按钮
私有子按钮1\u单击(发送者作为对象,e作为事件参数)处理按钮1。单击
“在使用它的地方附近,而不是在方法的顶部,暗淡的东西。”
'Dim myfilepath,test,test1,test2,i,strline
'我通常会反转此检查,如果不正常则返回-停止方法代码
'如果用户不需要,则从继续。命名你的OpenFileDialog
'比OpenFileDialog1更好
如果OpenFileDialog1.ShowDialogResult.OK,则返回
'您在这里创建了一些空数组,但这些数组没有多大用处(因此我将删除它们)
'因为在给定长度之前尝试访问它们,导致异常
'Dim cordx()
“昏暗的考迪()
"Dim cordz()
我将使用一个命名的ValueTuple;这是一个包含3个值的小类,
'这意味着我不必为它创建结构或类。因为我需要
'要存储多个,我将使用一个列表,其中。。。是命名的valuetuple:
Dim coords作为新列表(共有(xCoords为Double,yCoords为Double,zCoords为Double))
'读取文件一次,并存储行。您的代码读取整个文件只是为了找出有多少个文件
“有几行,然后再读一遍——浪费时间
'Dim satirlar=IO.File.ReadAllLines(myfilepath).Length
'注意,我刚从OpenFileDialog1中获得名称-无需将其存储在
“另一个变量。也不需要ToList()-ReadAllLines返回一个数组
Dim lines=IO.File.ReadAllLines(OpenFileDialog1.Filename)
'也不需要ToList()-ReadAllLines返回一个数组
'Dim lines=IO.File.ReadAllLines(myfilepath).ToList
'对于每个循环来说,读起来都比使用i。您不需要随机访问
'这里是数组,所以使用ForEach
'对于i=0到satirlar
每行中的每一行
如果line.ToLower().StartsWith(“点”)则
“不要使用Mid-这是旧的VB6命名法。使用子字符串
尺寸x=线。子串(24,8)
尺寸y=线。子串(32,8)
尺寸z=线。子串(40,8)
‘2.13-14应该是什么数字?’???在这里修复它:
x=x。替换(“-14”和“”)
y=y。替换(“-14”,”)
z=z。替换(“-14”和“”)
'这将生成一个命名的ValueTuple。您需要使用.net 4.7.2或使用Nuget安装System.ValueTuple
Dim t=(XCoord:=Convert.ToDouble(x),YCoord:=Convert.ToDouble(x),ZCoord:=Convert.ToDouble(z))
'将解析后的坐标添加到列表中
坐标添加(t)
如果结束
下一个
'现在您说要将其写入文件。好的,让我们做一个简单的CSV
'这使用LINQ访问coords列表中的每个元素
'并从包含3个双精度的ValueTuple转换为类似于1.0,2.0,3.3的字符串
Dim newFileLines=coords.Select(函数(c)$“{c.XCoord},{c.YCoord},{c.ZCoord}”).ToArray()
'将文件写回原始文件旁边的新文件,但扩展名为coords.csv
IO.File.WriteAllines(IO.Path.ChangeExtension(OpenFileDialog1.FileName,“coords.csv”),新文件行
端接头
实际上,如果您要做的只是将它们再次写入文件,那么我们可以跳过双重转换和其他类似的东西(valuetuple等):
Private子按钮1\u单击(发送者作为对象,e作为事件参数)处理按钮1。单击
如果OpenFileDialog1.ShowDialogResult.OK,则返回
标注换行符=新列表(字符串)
对于IO.File.ReadAllLines(OpenFileDialog1.Filename)中的每一行
如果line.ToLower().StartsWith(“点”)则
尺寸x=线。子串(24,8)
尺寸y=线。子串(32,8)
尺寸z=线。子串(40,8)
添加($“{x},{y},{z}”)
如果结束
下一个
IO.File.WriteAllines(IO.Path.ChangeExtension(OpenFileDialog1.FileName,“coords.csv”),换行符)
端接头
根据您的编辑,文本文件中的字段是固定宽度的。我用于测试的文本文件如下所示
POINTS 1 -5.15315 0.0 0.0
POINTS 2 -5.15315 0.0 0.0
POINTS 3 0.0 100.0 0.0
POINTS 4 100.0 100.0 0.0
POINTS 5 100.0 0.0 0.0
POINTS 6 100.0 105.325 200.0
POINTS 7 100.0 100.0 200.0
POINTS 8 -2.13-14 100.0 0.0
POINTS 9 100.0-1.42-14 0.0
POINTS 10 1.421-14-2.84-14 0.0
POINTS 11 -2.13-14 100.0 0.0
我为您的数据创建了一个简单的类。如果要保存数据,serializable属性很重要
<Serializable>
Public Class Coordinates
Public Property ID As Integer
Public Property CordX As String
Public Property CordY As String
Public Property CordZ As String
Public Overrides Function ToString() As String
Return $"ID {ID} X:{CordX} Y:{CordY} Z:{CordZ}"
End Function
End Class
为此,将调用以下方法之一
Private Sub FillCoordinatesListFromTextFile()
Dim lines = File.ReadAllLines("coordinates.txt")
For Each line In lines
If line.StartsWith("POINTS") Then
Dim crd As New Coordinates
'Indexes are zero based
'Substring(startIndex, Length)
crd.ID = CInt(line.Substring(7, 9).Trim)
crd.CordX = line.Substring(16, 16).Trim
crd.CordY = line.Substring(32, 8).Trim
crd.CordZ = line.Substring(40).Trim
CoordinateList.Add(crd)
End If
Next
'Just for testing
For Each cord In CoordinateList
Debug.Print(cord.ToString)
Next
End Sub
Private Sub FillCoordinateListFromXML()
Dim serial As New XmlSerializer(GetType(List(Of Coordinates)))
Using fs As New FileStream("coordinates.xml", FileMode.Open)
CoordinateList = DirectCast(serial.Deserialize(fs), List(Of Coordinates))
End Using
'Just for testing
For Each item In CoordinateList
Debug.Print(item.ToString)
Next
End Sub
下面是将数据保存到xml文件的方法。XML文件在记事本中是全文本和人类可读的
Private Sub SaveCoordinatesList()
Dim serializer = New XmlSerializer(GetType(List(Of Coordinates)))
Using writer As New StreamWriter("coordinates.xml")
serializer.Serialize(writer, CoordinateList)
End Using
End Sub
根据列表创建的结果xml文件为
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfCoordinates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Coordinates>
<ID>1</ID>
<CordX>-5.15315</CordX>
<CordY>0.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>2</ID>
<CordX>-5.15315</CordX>
<CordY>0.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>3</ID>
<CordX>0.0</CordX>
<CordY>100.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>4</ID>
<CordX>100.0</CordX>
<CordY>100.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>5</ID>
<CordX>100.0</CordX>
<CordY>0.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>6</ID>
<CordX>100.0</CordX>
<CordY>105.325</CordY>
<CordZ>200.0</CordZ>
</Coordinates>
<Coordinates>
<ID>7</ID>
<CordX>100.0</CordX>
<CordY>100.0</CordY>
<CordZ>200.0</CordZ>
</Coordinates>
<Coordinates>
<ID>8</ID>
<CordX>-2.13-14</CordX>
<CordY>100.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>9</ID>
<CordX>100.0</CordX>
<CordY>-1.42-14</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>10</ID>
<CordX>1.421-14</CordX>
<CordY>-2.84-14</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>11</ID>
<CordX>-2.13-14</CordX>
<CordY>100.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
</ArrayOfCoordinates>
当你说上面的代码失败时,你所说的失败到底是什么意思?获得意外输出的异常?我想我在您第一次发布此消息时问了这个问题
Private Sub SaveCoordinatesList()
Dim serializer = New XmlSerializer(GetType(List(Of Coordinates)))
Using writer As New StreamWriter("coordinates.xml")
serializer.Serialize(writer, CoordinateList)
End Using
End Sub
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfCoordinates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Coordinates>
<ID>1</ID>
<CordX>-5.15315</CordX>
<CordY>0.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>2</ID>
<CordX>-5.15315</CordX>
<CordY>0.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>3</ID>
<CordX>0.0</CordX>
<CordY>100.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>4</ID>
<CordX>100.0</CordX>
<CordY>100.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>5</ID>
<CordX>100.0</CordX>
<CordY>0.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>6</ID>
<CordX>100.0</CordX>
<CordY>105.325</CordY>
<CordZ>200.0</CordZ>
</Coordinates>
<Coordinates>
<ID>7</ID>
<CordX>100.0</CordX>
<CordY>100.0</CordY>
<CordZ>200.0</CordZ>
</Coordinates>
<Coordinates>
<ID>8</ID>
<CordX>-2.13-14</CordX>
<CordY>100.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>9</ID>
<CordX>100.0</CordX>
<CordY>-1.42-14</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>10</ID>
<CordX>1.421-14</CordX>
<CordY>-2.84-14</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
<Coordinates>
<ID>11</ID>
<CordX>-2.13-14</CordX>
<CordY>100.0</CordY>
<CordZ>0.0</CordZ>
</Coordinates>
</ArrayOfCoordinates>
Private Function GetCoordinateByID(Id As Integer) As Coordinates
Dim crd = (From c In CoordinateList
Where c.ID = Id
Select c).FirstOrDefault
Return crd
End Function
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim crd = GetCoordinateByID(2)
MessageBox.Show($"The X coordiante is {crd.CordX}")
End Sub