我想将代码从vb6迁移到vb.net.该项目非常基础(不使用dll或组件参考)只是模块
在压缩功能方面,它已经成功.我很开心.但是当解压缩子没有成功.程序挂了.我试过修复它,我发现问题是这样做..退出do..loop语句.
注意:代码在vb6中成功运行.
这是我的解压缩代码
Public Sub Decompress(ByteArray() As Byte) Dim InpPos As Long Dim InBitPos As Integer Dim LowValue As Long Dim HighValue As Long Dim RangValue As Long Dim MidValue As Long Dim Value As Long Dim mChar As Byte Dim i As Integer Dim Index As Integer Dim EOF_State As Boolean Dim TopBit As Long Dim One(256) As Long Dim Zero(256) As Long Call Initiate LowValue = 0 HighValue = (2 ^ MaxBits) - 1 TopBit = 2 ^ (MaxBits - 1) InpPos = 0 Value = ReadBitsFromArray(ByteArray, InpPos, InBitPos, MaxBits) Index = -1 For i = 0 To 256 One(i) = 1 Zero(i) = 1 Next Do mChar = 0 For i = 0 To 7 Index = (1 * (2 ^ i)) - 1 + mChar RangValue = HighValue - LowValue MidValue = LowValue + (RangValue * (Zero(Index) / (One(Index) + Zero(Index)))) If MidValue = LowValue Then MidValue = MidValue + 1 If MidValue = HighValue - 1 Then MidValue = MidValue - 1 If Value >= MidValue Then mChar = (2 * mChar) + 1 LowValue = MidValue One(Index) = One(Index) + 1 Else mChar = 2 * mChar HighValue = MidValue Zero(Index) = Zero(Index) + 1 End If Do While (HighValue And TopBit) = (LowValue And TopBit) Or LowValue > HighValue - 255 If InpPos <= UBound(ByteArray) Then Value = (Value And (TopBit - 1)) * 2 + ReadBitsFromArray(ByteArray, InpPos, InBitPos, 1) HighValue = (HighValue And (TopBit - 1)) * 2 + 1 LowValue = (LowValue And (TopBit - 1)) * 2 If LowValue >= HighValue Then HighValue = (2 ^ MaxBits) - 1 Else EOF_State = True Exit Do End If Loop If EOF_State = True Then Exit Do Next Call AddmCharToArray(OutStream, OutPos, mChar) Loop ReDim Preserve OutStream(OutPos - 1) End Sub Private Sub Initiate() ReDim OutStream(500) OutPos = 0 OutBitCount = 0 OutByteBuf = 0 End Sub Private Sub AddBitsToOutStream(Number As Integer) OutByteBuf = OutByteBuf * 2 + Number OutBitCount = OutBitCount + 1 If OutBitCount = 8 Then OutStream(OutPos) = OutByteBuf OutBitCount = 0 OutByteBuf = 0 OutPos = OutPos + 1 If OutPos > UBound(OutStream) Then ReDim Preserve OutStream(OutPos + 500) End If End If End Sub Private Function ReadBitsFromArray(FromArray() As Byte, FromPos As Long, FromBit As Integer, NumBits As Integer) As Long Dim i As Integer Dim Temp As Long For i = 1 To NumBits Temp = Temp * 2 + (-1 * ((FromArray(FromPos) And 2 ^ (7 - FromBit)) > 0)) FromBit = FromBit + 1 If FromBit = 8 Then If FromPos + 1 > UBound(FromArray) Then Do While i < NumBits Temp = Temp * 2 i = i + 1 Loop FromPos = FromPos + 1 Exit For End If FromPos = FromPos + 1 FromBit = 0 End If Next ReadBitsFromArray = Temp End Function Private Sub AddmCharToArray(ToArray() As Byte, ToPos As Long, mChar As Byte) If ToPos > UBound(ToArray) Then ReDim Preserve ToArray(ToPos + 500) ToArray(ToPos) = mChar ToPos = ToPos + 1 End Sub
do..exit做..
Do mChar = 0 For i = 0 To 7 Index = (1 * (2 ^ i)) - 1 + mChar RangValue = HighValue - LowValue MidValue = LowValue + (RangValue * (Zero(Index) / (One(Index) + Zero(Index)))) If MidValue = LowValue Then MidValue = MidValue + 1 If MidValue = HighValue - 1 Then MidValue = MidValue - 1 If Value >= MidValue Then mChar = (2 * mChar) + 1 LowValue = MidValue One(Index) = One(Index) + 1 Else mChar = 2 * mChar HighValue = MidValue Zero(Index) = Zero(Index) + 1 End If Do While (HighValue And TopBit) = (LowValue And TopBit) Or LowValue > HighValue - 255 If InpPos <= UBound(ByteArray) Then Value = (Value And (TopBit - 1)) * 2 + ReadBitsFromArray(ByteArray, InpPos, InBitPos, 1) HighValue = (HighValue And (TopBit - 1)) * 2 + 1 LowValue = (LowValue And (TopBit - 1)) * 2 If LowValue >= HighValue Then HighValue = (2 ^ MaxBits) - 1 Else EOF_State = True Exit Do End If Loop If EOF_State = True Then Exit Do Next Call AddmCharToArray(OutStream, OutPos, mChar) Loop
对不起,我不能写好英语.
Private Function ReadBitsFromArray(FromArray() As Byte, FromPos As Long, ...)
该错误位于此函数声明中.您的循环只能在InpPos
超出数组上限的增量时退出,并将EOF_State
变量设置为True.循环本身根本不会增加InpPos.回到VB6,它由ReadBitsFromArray()函数FromBit = FromBit + 1
声明增加.但在VB.NET中已不再是这种情况.
VB.NET的一个重要变化是参数的传递方式.旧的Visual Basic版本默认为ByRef
.一个有点奇怪的选择,其原因在时间的迷雾中消失了.传递参数是一种非常昂贵的方法,传递ByRef需要传递指向值而不是值本身的指针.每次访问变量都需要指针取消引用.它比现代机器上的值传递速度慢至少3倍,.NET经过大量优化,可以通过CPU寄存器而不是堆栈传递参数值,如果参数通过引用传递,则无法工作.
所以VB.NET ByVal
默认了.由于您未明确声明它,因此默认值适用并按InpPos
值传递.永远不要增加,这在调试器中很容易看到.固定:
Private Function ReadBitsFromArray(ByVal FromArray() As Byte, _ ByRef FromPos As Integer, _ ByVal FromBit As Integer, _ ByVal NumBits As Integer) As Integer
请注意,Long和Integer之间的选择是您必须要担心的其他事项.VB6 Long是一个VB.NET Integer.我猜想Integer在这里是合适的.请考虑将.NET GZipStream类作为替代方案,它听起来不像你记得它仍然能够维护这段代码的方式.