我正在尝试在vb.net(窗体)中创建一个程序来处理来自UVvis光谱仪的数据。
txt文件输出如下。
"180809_QuartzRefTrans.spc - RawData" "Wavelength nm.","T%" 400.00,90.822 401.00,90.800 402.00,90.823 403.00,90.811 404.00,90.803 405.00,90.804 406.00,90.816 407.00,90.811 408.00,90.833 409.00,90.837 410.00,90.847 411.00,90.827 412.00,90.839 413.00,90.851 414.00,90.828 415.00,90.879 416.00,90.846
,依此类推。
我想做的是将数据读入数组,以便可以操作列。我需要能够跳过前两行,以便我所拥有的只是数值数据。我还需要它从最低到最高(波长)对数组进行排序。有时我们从800-> 200 nm运行,然后不小心放入200-> 800 nm
Imports System.IO
Imports System.Windows.Forms.DataVisualization.Charting
Public Class Form1
Public Class RefTrans
Public Property Wavelength As Double
Public Property Transpercent As Double
End Class
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim strtext As String
OpenFileDialog1.Title = "Open Text Files"
OpenFileDialog1.ShowDialog()
strtext = OpenFileDialog1.FileName
TextBox1.Text = My.Computer.FileSystem.GetName(strtext)
Label1.Text = My.Computer.FileSystem.GetName(strtext)
Dim line1 As String
Dim output1 As New ArrayList
Using sr As New IO.StreamReader(strtext)
sr.ReadLine()
sr.ReadLine()
Do While sr.Peek() >= 0
line1 = sr.ReadLine()
output1.Add(line1)
Loop
End Using
If strtext <> "" Then
Dim SR As New StreamReader(strtext)
SR.ReadLine()
Do Until SR.EndOfStream
TextBox3.Text = TextBox3.Text & SR.ReadLine & vbCrLf
Loop
SR.Close()
End If
Dim data1 = IO.File.ReadLines(strtext).
Skip(2).
Select(Function(line)
Dim parts = line.Split(","c)
Return New RefTrans With {.Wavelength = CDbl(parts(0)),
.Transpercent = CDbl(parts(1))}
End Function).
ToArray() = line.Split(","c)
End Sub
End Class
答案 0 :(得分:0)
下面是一个示例,它将为您提供Tuple(Of Double, Double)
的数组:
Dim data = IO.File.ReadLines(filePath).
Skip(2).
Select(Function(line)
Dim parts = line.Split(","c)
Return Tuple.Create(CDbl(parts(0)), CDbl(parts(1)))
End Function).
ToArray()
IO.File.ReadLines
方法将读取文件的行。在ReadAllLines
方法读取整个文件然后将行作为String
数组返回的情况下,ReadLines
方法将文件的行显示为可枚举的列表,并且仅从中读取行使用它们时的文件。特别是对于大文件,ReadLines
比ReadAllLines
更有效率,因为它确实会首先创建您实际上不想要的中间数组。
通过Skip
方法,您可以访问从特定索引开始的列表中的项目。在读取文件的情况下,您需要读取每一行,无论如何,但是对Skip(2)
的结果调用File.ReadLines
意味着读取后文件的前两行将被丢弃,并且随后的任何处理将只不过是从第三行开始。
Select
方法基本上是一种转换。它表示为输入列表中的每个项目创建一个包含一个项目的输出列表,其中输出项目是输入项目转换的结果。转换由您提供的功能定义。在这种情况下,将输入文件中的一行,然后进行转换,以逗号分隔该行,将两个子字符串转换为Double
值,然后创建一个包含这两个{{1 }}值。
Tuple
方法采用任何可枚举的列表,即实现Double
的任何对象,并返回一个包含该列表中各项的数组。在这种情况下,ToArray
返回一个IEnumerable(Of T)
,因此Select
返回一个IEnumerable(Of Tuple(Of Double, Double))
数组。
如果您想将所有内容全部写下来,那么它将看起来像这样:
ToArray
Tuple(Of Double, Double)
基本上是将值分组在一起的通用对象。您可以将'Get all the lines of the file.
Dim step1 As IEnumerable(Of String) = IO.File.ReadLines(filePath)
'Skip the first two lines.
Dim step2 As IEnumerable(Of String) = step1.Skip(2)
'Split each line into two substrings.
Dim step3 As IEnumerable(Of String()) = step2.Select(Function(line) line.Split(","c))
'Convert substrings to numbers and combine.
Dim step4 As IEnumerable(Of Tuple(Of Double, Double)) = step3.Select(Function(parts) Tuple.Create(CDbl(parts(0)), CDbl(parts(1))))
'Create an array of Tuples.
Dim data As Tuple(Of Double, Double)() = step4.ToArray()
用于一次性案例,而不用定义自己的类。不过,您可能更愿意在所有情况下都定义自己的类,并且应该定义自己的类,以广泛使用数据。在这种情况下,您自己的类可能如下所示:
Tuple
,代码将变为:
Tuple
在这种情况下,数组的每个元素上都有属性Public Class RefTrans
Public Property Wavelength As Double
Public Property TransPercent As Double
End Class
和Dim data = IO.File.ReadLines(filePath).
Skip(2).
Select(Function(line)
Dim parts = line.Split(","c)
Return New RefTrans With {.Wavelength = CDbl(parts(0)),
.TransPercent = CDbl(parts(1))}
End Function).
ToArray()
。如果使用Wavelength
,则属性具有通用名称TransPercent
和Tuples
。
有了数组后,就可以使用Item1
的任何适当的重载来进行排序,例如
Item2
这将通过比较Array.Sort
的{{1}}属性(包含波长值)来对Array.Sort(data, Function(d1, d2) d1.Item1.CompareTo(d2.Item1))
进行排序。如果您使用自己的类,那么显然您可以指定自己的属性,例如我展示的Tuples
类中的Item1
属性。