2012-04-04 14 views
1

語言: vb.net 文件大小:1GB和東西。如何確保文件在vb.net中具有唯一的行如果文件的大小非常大

文本文件的編碼: UTF8(因此每個字符由不同數量的字節表示)。

整理: UnicodeCI(當幾個字符基本相同時,最流行的版本將是唯一的版本。)。我想我知道如何處理他的問題。

由於每個字符都由不同數量的字節表示,並且每行的字符數不同,因此每行中的字節數也各不相同。

我想我們必須爲每一行計算哈希。我們還需要將緩衝區的位置存儲在每行的位置。然後我們必須比較緩衝區。然後我們將檢查是否顯示同一行。

是否有最適合此功能的特殊功能?

回答

1

根據線有多長,你可以計算的MD5哈希值的每一行和存儲比在HashMap

Using sr As New StreamReader("myFile") 
    Dim lines As New HashSet(Of String) 
    Dim md5 As New Security.Cryptography.MD5Cng() 

    While sr.BaseStream.Position < sr.BaseStream.Length 
     Dim l As String = sr.ReadLine() 
     Dim hash As String = String.Join(String.Empty, md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(l)).Select(Function(x) x.ToString("x2"))) 

     If lines.Contains(hash) Then 
      'Lines are not unique 
      Exit While 
     Else 
      lines.Add(hash) 
     End If 
    End While 
End Using 

未經檢驗的,但是這可能是你需要足夠快。我不能想到的東西更快仍然保持簡潔的:)

+0

什麼是MD5的大小?一個不完美的方法是使用壓縮內存的整數散列。但是再次,幾條不同的線必須具有相同的散列。這就是爲什麼我們也需要存儲緩衝區位置。 – 2012-04-04 04:46:14

+0

+1我也大量修改了你的代碼。該退出雖然是一個bug,等等。 – 2012-04-04 05:57:54

+0

sr.BaseStream.Position 2012-04-04 06:40:02

0

一些外表這是當代答案

Public Sub makeUniqueForLargeFiles(ByVal strFileSource As String) 
    Using sr As New System.IO.StreamReader(strFileSource) 
     Dim changeFileName = reserveFileName(strFileSource, False, True) 
     Using sw As New System.IO.StreamWriter(reserveFileName(strFileSource, False, True), False, defaultEncoding) 
      sr.Peek() 
      Dim lines As New Generic.Dictionary(Of Integer, System.Collections.Generic.List(Of Long)) 
      While sr.BaseStream.Position < sr.BaseStream.Length 
       Dim offset = sr.BaseStream.Position 
       Dim l As String = sr.ReadLine() 
       Dim nextOffset = sr.BaseStream.Position 
       Dim hash = l.GetHashCode 
       Do ' a trick to put the for each in a "nest" that we can exit from 
        If lines.ContainsKey(hash) Then 
         Using sr2 = New System.IO.StreamReader(strFileSource) 
          For Each offset1 In lines.Item(hash) 
           sr2.BaseStream.Position = offset1 
           Dim l2 = sr2.ReadLine 
           If l = l2 Then 
            Exit Do 'will sr2.dispose be called here? 
           End If 
          Next 
         End Using 
        Else 
         lines.Add(hash, New Generic.List(Of Long)) 
        End If 
        lines.Item(hash).Add(offset) 
        sw.WriteLine(l) 
       Loop While False 
       sr.BaseStream.Position = nextOffset 
      End While 
     End Using 
    End Using 
End Sub 
相關問題