2013-10-28 58 views
0

我正在逐个字节地读取一个小的二进制文件(大约32mb)到数据表中,并将前八个字节从十六进制转换为二进制。读取小的二进制文件,内存不足异常

对于大文件,我遇到系统内存异常错误消息,我无法考虑如何提高我的代码运行更平稳或更快。

这是我的代码:

Public Function DecToBin(ByVal DeciValue As Long, Optional ByVal NoOfBits As Integer = 8) As String 
    Dim i As Integer 
    Do While DeciValue > (2^NoOfBits) - 1 
     NoOfBits = NoOfBits + 8 
    Loop 
    DecToBin = vbNullString 
    For i = 0 To (NoOfBits - 1) 
     DecToBin = CStr((DeciValue And 2^i)/2^i) & DecToBin 
    Next i 
End Function 

Private Sub importData(ByVal openFile As String) 
    If fullFilePath.EndsWith("variable.dat") Then 
     Dim importedData As New DataTable 
     Cursor.Current = Cursors.WaitCursor 
     Using reader As New BinaryReader(File.Open(openFile, FileMode.Open)) 
      Dim pos As Integer = 0 
      Dim length As Integer = reader.BaseStream.Length 
      loadingBar.loadingLabel.Text = "Lines of data: " & length 

      loadingBar.loadingProgress.Minimum = 0 
      loadingBar.loadingProgress.Maximum = length 
      loadingBar.loadingProgress.Step = 1 

      importedData.Columns.Add("Data0") 
      importedData.Columns.Add("Data1") 
      importedData.Columns.Add("Data2") 
      importedData.Columns.Add("Data3") 
      importedData.Columns.Add("Data4") 
      importedData.Columns.Add("Data5") 
      importedData.Columns.Add("Data6") 
      importedData.Columns.Add("Data7") 

      importedData.Columns.Add("Time") 
      importedData.Columns.Add("Date") 

      importedData.Columns.Add("Day") 
      importedData.Columns.Add("Month") 
      importedData.Columns.Add("Year") 

      importedData.Columns.Add("Blank") 

      While pos < length 

       For i = 0 To 15 
        Dim value As Decimal = reader.ReadByte 
        rawDataArray(i) = value.ToString() 
        pos += 1 
       Next 

       loadingBar.BringToFront() 
       loadingBar.Show() 
       Cursor.Current = Cursors.WaitCursor 

       loadingBar.loadingProgress.Value = pos 


       convertedDataArray(0) = DecToBin(rawDataArray(0)) 
       convertedDataArray(1) = DecToBin(rawDataArray(1)) 
       convertedDataArray(2) = DecToBin(rawDataArray(2)) 
       convertedDataArray(3) = DecToBin(rawDataArray(3)) 
       convertedDataArray(4) = DecToBin(rawDataArray(4)) 
       convertedDataArray(5) = DecToBin(rawDataArray(5)) 
       convertedDataArray(6) = DecToBin(rawDataArray(6)) 
       convertedDataArray(7) = DecToBin(rawDataArray(7)) 

       convertedDataArray(8) = Format((rawDataArray(12) + 0), "00") & ":" & Format((rawDataArray(11) + 0), "00") & ":" & Format((rawDataArray(10) + 0), "00") & "." & Format((rawDataArray(8) * 256) + rawDataArray(9), "000") 
       convertedDataArray(9) = Format((rawDataArray(13) + 0), "00") & "." & Format((rawDataArray(14) + 0), "00") & "." & "20" & Format((rawDataArray(15) + 0), "00") 

       convertedDataArray(10) = Format((rawDataArray(13) + 0), "00") 
       convertedDataArray(11) = Format((rawDataArray(14) + 0), "00") 
       convertedDataArray(12) = Format((rawDataArray(15) + 0), "00") 

       importedData.Rows.Add(convertedDataArray) 
       Application.DoEvents() 
      End While 
      loadingBar.Close() 
      importedData.DefaultView.Sort = "Year,Month,Day,Time" 
      dataGrid.DataSource = importedData.DefaultView 
     End Using 
     dataGrid.Columns(0).Visible = False ' Data 0 
     dataGrid.Columns(1).Visible = False ' Data 1 
     dataGrid.Columns(2).Visible = False ' Data 2 
     dataGrid.Columns(3).Visible = False ' Data 3 
     dataGrid.Columns(4).Visible = False ' Data 4 
     dataGrid.Columns(5).Visible = False ' Data 5 
     dataGrid.Columns(6).Visible = False ' Data 6 
     dataGrid.Columns(7).Visible = False ' Data 7 
     dataGrid.Columns(8).Visible = True ' Data Time 
     dataGrid.Columns(9).Visible = True ' Data Date 
     dataGrid.Columns(10).Visible = False ' Data Day 
     dataGrid.Columns(11).Visible = False ' Data Month 
     dataGrid.Columns(12).Visible = False ' Data Year 
     dataGrid.Columns(13).Visible = False ' Data Blank 

    Else 
     MsgBox("Wrong file selected") 
    End If 
End Sub 

数据的实施例正被读取:

3F F3 45 C6 03 00 11 00 00 6F 1F 1D 16 12 07 0D

输出示例:

00111111 1 1110011 01000101 11000110 00000011 00000000 00010001 00000000 22:29:31.111 2013年7月18日18 07 13

+0

该问题属于codereview – Peter

+0

@peer我看不出来;它正在询问一个特定的问题 - 处理什么是OOM,尽管OP的描述是*** *** ***文件 –

+1

你为什么要做所有'ToString()'/'DecToBin'的东西? 'ReadByte()'已经***返回一个'byte' ***(具体地说,它返回一个'int',它对于EOF来说是否定的,或者在0-255范围内 - 它只需要被转换为'字节'和:工作完成):你有什么样的输入/输出你正在做什么?因为它看起来很像你在这里发明的工作......另外:'convertedDataArray'的类型是什么? (它没有显示) –

回答

1

四处System.OutOfMemoryException意味着有可用的所需尺寸的未分配存储器的任何单一连续区域。这并不一定意味着你没有留下记忆,而是记忆太分散了。

解决该问题的一种方法可能是使用MemoryMappedFile类(顾名思义)将进程的虚拟内存的一部分映射到硬盘上的数据。

你可以尝试处理这个问题的另一种方法是调用GC.Collect这将压缩内存作为垃圾收集过程的一部分。虽然,我强烈劝阻使用这种方法。

您可以使用ANTS Memory Profiler或windbg(作为Windows SDK的一部分发送)来查看您的内存在何处使用。

至于你的代码,你似乎没有任何可疑的东西(除了Marc Gravell已经指出的DecToBin)。

希望这会有所帮助。