我正在研究一种方法,该方法接收一个文本文件,并将该文件缩减至约10 MB。此方法用于截断日志文件并将其保持在10 MB限制内。
代码的逻辑基本上是这样的...如果文件大小为250 MB或更大,则读取字节直到数组达到250 MB。将其存储到StringBuilder中,设置下一次读取的位置并重复操作,直到StringBuilder包含约10 MB的数据。然后写入文件并擦除所有数据,仅留下最近写入的10 MB数据。
为了防止切割行,它会检查最后一个CrLf的位置,然后从该点向前写出所有数据。
我的问题是,我无法使seek在第一次读取后正确定位。它首先正确读取数据,然后当我使用上一次读取的位置进行下一次迭代时,它会“忽略”该位置并再次从文件开头读取。
代码的逻辑基本上是这样的...如果文件大小为250 MB或更大,则读取字节直到数组达到250 MB。将其存储到StringBuilder中,设置下一次读取的位置并重复操作,直到StringBuilder包含约10 MB的数据。然后写入文件并擦除所有数据,仅留下最近写入的10 MB数据。
为了防止切割行,它会检查最后一个CrLf的位置,然后从该点向前写出所有数据。
我的问题是,我无法使seek在第一次读取后正确定位。它首先正确读取数据,然后当我使用上一次读取的位置进行下一次迭代时,它会“忽略”该位置并再次从文件开头读取。
If logFile.Length > (1024 * 1024 * 250) Then
Dim DataToDelete As Integer = logFile.Length - (1024 * 1024 * 250)
Dim ArrayIndex As Integer = 0
While DataToDelete > 0
Using fs As FileStream = New FileStream(logFile.FullName, FileMode.Open, FileAccess.ReadWrite)
fs.Seek(ArrayIndex, SeekOrigin.Begin)
If strBuilder.Length < (1024 * 1024 * 250) Then
Dim bytes() As Byte = New Byte((1024 * 1024 * 250)) {}
Dim n As Integer = fs.Read(bytes, 0, (1024 * 1024 * 250))
ArrayIndex = bytes.Length
Dim enc As Encoding = Encoding.UTF8
strBuilder.Append(enc.GetString(bytes))
Else
If DataToDelete - strBuilder.Length < 0 And strBuilder.Length > (1024 * 1024 * My.Settings.Threshold) Then
Dim DataToCut As Integer = strBuilder.Length - (1024 * 1024 * My.Settings.Threshold)
While Not (strBuilder.Chars(DataToCut).ToString.Equals(vbCr)) And DataToCut <> 0
DataToCut -= 1
End While
strBuilder.Remove(0, DataToCut)
File.WriteAllText(logFile.FullName, strBuilder.ToString)
Else
DataToDelete -= strBuilder.Length
strBuilder.Clear()
End If
End If
End Using
End While
End If