[英]Best way to search large file for data in .net
我正在一个项目中,在其中搜索大文本文件(相对较大,文件大小约为1 Gig)以查找数据。 我正在寻找一个令牌,并且我希望该令牌后立即有美元价值。 例如,
这是令牌9,999,999.99
所以这就是我解决这个问题的方法。 经过一点分析后,令牌通常位于文件末尾附近,因此我认为我将从文件末尾开始搜索。 这是我到目前为止的代码(vb.net):
Dim sToken As String = "This is a token"
Dim sr As New StreamReader(sFileName_IN)
Dim FileSize As Long = GetFileSize(sFileName_IN)
Dim BlockSize As Integer = CInt(FileSize / 1000)
Dim buffer(BlockSize) As Char
Dim Position As Long = -BlockSize
Dim sBuffer As String
Dim CurrentBlock As Integer = 0
Dim Value As Double
Dim i As Integer
Dim found As Boolean = False
While Not found And CurrentBlock < 1000
CurrentBlock += 1
Position = -CurrentBlock * BlockSize
sr.BaseStream.Seek(Position, SeekOrigin.End)
i = sr.ReadBlock(buffer, 0, BlockSize)
sBuffer = New String(buffer)
found = SearchBuffer(sBuffer, sToken, Value)
End While
GetFileSize是一个返回文件大小的函数。 SearchBuffer是一个将在字符串中搜索令牌的函数。 我对正则表达式不熟悉,但会针对该函数进行探讨。
基本上我读了文件的一小部分进行搜索,如果找不到,则加载另一个文件,依此类推...
我是在正确的轨道上还是有更好的方法?
我认为您对文件进行分块时有正确的主意。 不过,您可能想在换行符处读取块,而不是读取一定数量的字节。 在当前的实现中,如果令牌位于1000字节边界上,则令牌可能会切成两半,从而无法找到它。 同样的事情也可能导致数据被切断。
等你...
如果令牌在两个块之间被破坏怎么办? 你有考虑过吗?
如果要使用块,明智的做法是使用长度为512字节的倍数的块,并尝试以512字节对齐,因为这样做通常会更有效地访问磁盘(最终将存储在磁盘中)。 512字节块)。
可能还有其他更好的粒度,但是512将是一个好的开始。
如果您想做一些更复杂但又可能更快的事情,那么您可以看一下异步读取这些块的方法,以便在下一个正在加载的同时进行搜索。
这样,您就可以在数据进入内存的同时执行搜索。
我不得不说,除非您的搜索非常昂贵,否则磁盘读取时间可能会完全主导这一点,因此,复杂的重叠将不值得额外的复杂性。
“如果令牌在两个块之间被破坏怎么办?您考虑过吗?”
最近才做的。 我先将CurrentBlock保存到PreviousBlock中,然后再覆盖CurrentBlock,然后将这两个Block结合起来,并检查找到所需的搜索词是否愉快! 效果很好。 除非搜索词大于块的长度,否则搜索词不能转义。
您始终可以使用FileStream在文件中进行搜索(也可以按照自己的选择继续进行操作)。 如果您决定使用FileStream方法,那么您将要执行以下操作:
Dim stream As New FileStream("something.txt")
Dim findBytes As [Byte]() = BitConverter.GetBytes("whatever")
Dim f As Integer = 0
' remaining = Length - Position
While stream.Length - stream.Position > 0
If stream.ReadByte() = findBytes(f) Then
If ++f >= findBytes.Length Then
Console.WriteLine(stream.Position)
Exit While
End If
Else
f = 0
End If
End While
只是要注意,我使用了ac#到vb转换器,因为我不喜欢vb。
基本思想适用于仅在块中搜索字符串。 如果要以块为单位添加阅读,这非常简单。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.