VB.net对MFC记录式文件的读取实践代码

在项目开发中,在MFC下生成的文件,需要用VB.net进行读取;MFC是用CFile类生成的记录式文件,每条记录是一个结构体。

代码开放,遵循但不限于PCL协议,给予代码复制者商业软件使用特权;但是使用者必须是开源社区忠实拥护和推广者,即代码必须免费开放。

1.首先加载一个模块;在模块中对MFC的结构体进行复制定义,源码如下:

Imports System.Runtime.InteropServices
Imports System.IO
Module Module1
    '**************读取文件结构体*********************

‘结构体声明必须加上这个属性定义语句,整个定义如下:
    <StructLayoutAttribute(LayoutKind.Sequential, CharSet:=CharSet.Auto, Size:=96)> _
    Public Structure tagTestDatas
        Dim dTemperature As Double
        Dim dHumidity As Double
        Dim dEnvHumidity As Double
        Dim dFlowRate As Double
        Dim dOxyAD As Double
        Dim dOTR As Double
        Dim dppm As Double
        Dim dtime As Double
        Dim dValtage As Double
        Dim dVsteam As Double
        Dim dZeroppm As Double
        Dim dStandardOTR As Double
    End Structure
    Public TestData As tagTestDatas
    '**************************************************
    '##################结构体和字节数组的转换##########
    Public Sub StructToBytes(ByVal objStruct As Object, ByRef bytes() As Byte)
        '得到结构体长度 
        Dim size As Integer = Marshal.SizeOf(objStruct)
        '重新定义数组大小 
        ReDim bytes(size)
        '分配结构体大小的内存空间 
        Dim ptrStruct As IntPtr = Marshal.AllocHGlobal(size)
        '将结构体放入内存空间 
        Marshal.StructureToPtr(objStruct, ptrStruct, False)
        '将内存拷贝到字节数组 
        Marshal.Copy(ptrStruct, bytes, 0, size)
        '释放内存空间 
        Marshal.FreeHGlobal(ptrStruct)
    End Sub

    ' 字节数组bytes()转化为结构体 
    Public Function BytesToStruct(ByRef bytes() As Byte, ByVal mytype As Type) As Object
        '获取结构体大小 
        Dim size As Integer = Marshal.SizeOf(mytype)
        'bytes数组长度小于结构体大小 
        If (size > bytes.Length) Then
            '返回空 
            Return (Nothing)
        End If
        '分配结构体大小的内存空间 
        Dim ptrStruct As IntPtr = Marshal.AllocHGlobal(size)
        '将数组拷贝到内存 
        Marshal.Copy(bytes, 0, ptrStruct, size)
        '将内存转换为目标结构体 
        Dim obj As Object = Marshal.PtrToStructure(ptrStruct, mytype)
        '释放内存 
        Marshal.FreeHGlobal(ptrStruct)
        Return (obj)
    End Function
    ' 从文件中读取结构体 
    Public Function FileToStruct(ByVal strPath As String, ByVal mytype As Type) As Object
        '获得结构体大小 
        Dim size As Integer = Marshal.SizeOf(mytype)
        '打开文件流 
        Dim fs As New FileStream(strPath, FileMode.Open)
        '读取size个字节 
        Dim bytes(size) As Byte
        fs.Read(bytes, 0, size)
        '将读取的字节转化为结构体 
        Dim obj As Object = BytesToStruct(bytes, mytype)
        fs.Close()
        Return (obj)
    End Function
    '从文件读取二进制流返回字节数组
    Public Function ReadInfo(ByVal strPath As String) As Byte()
        Try
            Dim fs As New FileStream(strPath, FileMode.Open)
            Dim br As BinaryReader = New BinaryReader(fs)
            Dim bt() As Byte = br.ReadBytes(fs.Length)
            br.Close()
            fs.Close()
            Return bt
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

 

    '################################################
    Public StrFileName As String = ""

 ’项目启动设为sub main(),这是带参数的main()函数定义格式:
    Sub main(ByVal args() As String)
        If UBound(args) >= 0 Then
            StrFileName = args(0).ToString
        Else
            StrFileName = ""
        End If

      ‘application.run()运行程序才能改变项目启动项,窗体程序才能从sub main()启动项目中启动运行。
        Dim frm1 As New Form1
        Application.Run(frm1)
    End Sub
End Module
2.加载一个窗体,进行文件读取和显示;我的项目是在CE5.0下的,这个窗体的作用是读取MFC文件内容给自定义画曲线控件,完成曲线绘制功能。代码如下:

Imports System.Runtime.InteropServices
Imports System.IO
Public Class Form1
    '程序运行目录
    Public curDir As String = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase().ToString())

    Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        Me.CeGraphCurve1.Dispose()
        Me.Close()
        Me.Dispose()
        GC.Collect()
    End Sub
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Location = New Point((Screen.PrimaryScreen.WorkingArea.Width - Me.ClientSize.Width) / 2, (Screen.PrimaryScreen.WorkingArea.Height - Me.ClientSize.Height) / 2)
        Me.TopMost = True
        Me.CeGraphCurve1.YAxisTitle = "Red:Temp(℃)---Green:RH(%)"
        Me.Button1.Location = New Point((Me.Width - Me.Button1.Width) / 2, Me.Button1.Location.Y)
    End Sub
    Private Sub Form1_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.LostFocus
        Me.TopMost = True
    End Sub

//读取文件主要模块代码
    Private Sub InitGraph()
        If System.IO.File.Exists(curDir & "\data\" & StrFileName) = True Then
            '开始读取文件
            Dim bt() As Byte = ReadInfo(curDir & "\data\" & StrFileName)
            Dim pointsX() As Single
            Dim pointsY() As Single
            pointsX = Nothing
            pointsY = Nothing
            Dim HpointsX() As Single
            Dim HpointsY() As Single
            HpointsX = Nothing
            HpointsY = Nothing
            If IsNothing(bt) = False Then
                Dim structSize As Integer = Marshal.SizeOf(GetType(tagTestDatas))
                Dim num As Integer = (UBound(bt)+1) / structSize
                ReDim pointsX(num - 1)
                ReDim pointsY(num - 1)
                ReDim HpointsX(num - 1)
                ReDim HpointsY(num - 1)
               
                For i As Integer = 0 To num - 1
                    Dim temp(structSize - 1) As Byte
                    Array.Copy(bt, i * structSize, temp, 0, structSize)
                    TestData = BytesToStruct(temp, GetType(tagTestDatas))
                    pointsX(i) = TestData.dtime
                    pointsY(i) = Format(TestData.dTemperature, "0.00")
                    HpointsX(i) = TestData.dtime
                    HpointsY(i) = Format(TestData.dHumidity, "0.00")
                Next
                Me.CeGraphCurve1.AddPointPairs(pointsX, pointsY)
                Me.CeGraphCurve1.AddPointPairs(HpointsX, HpointsY)
                Me.CeGraphCurve1.DrawCurve()
                pointsX = Nothing
                pointsY = Nothing
                HpointsX = Nothing
                HpointsY = Nothing
                GC.Collect()
            End If
        End If
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If StrFileName <> "" Then
            Me.Button1.Enabled = False
            Me.CeGraphCurve1.ClearPoints()
            InitGraph()
            Me.Button1.Enabled = True
        Else
            MsgBox("No Chance File!", MsgBoxStyle.Information, "Info")
        End If
    End Sub
   
End Class

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值