Vb.net 如何使用Visual Basic从文本文件中获取点坐标?

Vb.net 如何使用Visual Basic从文本文件中获取点坐标?,vb.net,Vb.net,我想从文本文件中获取点坐标。文本文件太长。你可以在下面找到一个样本 示例文本 点数据 美元 $$ --------------------------------------------------------------------------------$ $$组定义$ $$------------------------------------------------------------------------------$ 首先,我不擅长编码,如果你简单地告诉我,我将不胜感激 目的是

我想从文本文件中获取点坐标。文本文件太长。你可以在下面找到一个样本

示例文本

点数据

美元

$$ --------------------------------------------------------------------------------$ $$组定义$ $$------------------------------------------------------------------------------$

首先,我不擅长编码,如果你简单地告诉我,我将不胜感激

目的是获取点id和坐标

  • 1-读取所有文本文件

    2-查找文本长度(行计数)

    3-创建从0开始到(行计数)的for循环

    4-检测以“点”开头的线条(我想使用 中间(线(i)),0,5)=“点”)

    5-如果中间(线(i)),则使用0,5)=“点”,然后 中间(线(i)),25,33)=跳线(i)

    6-最后将此数组写入文本文件

  • 我尝试使用的代码,但是失败了

    我正在使用VisualStudio2019。 致意

        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