2012-04-04 80 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 
相关问题