我们正在将 VB6 应用程序转换为 C# (4.0)。并且在 VB6 中遇到了一种我们正在努力理解的方法。
Public Sub SaveToField(fldAttach As ADODB.Field)
Dim bData() As Byte
Dim nSize As Long
nSize = Len(m_sEmail)
bData = LngToByteArray(nSize)
fldAttach.AppendChunk bData
If nSize > 0 Then
bData = StringToByteArray(m_sEmail)
fldAttach.AppendChunk bData
End If
nSize = Len(m_sName)
bData = LngToByteArray(nSize)
fldAttach.AppendChunk bData
If nSize > 0 Then
bData = StringToByteArray(m_sName)
fldAttach.AppendChunk bData
End If
bData = LngToByteArray(m_nContactID)
fldAttach.AppendChunk bData
End Sub
它似乎在做一些二进制文件复制类型的事情,但我不太了解。有人可以解释一下,以便我们重写吗?
最佳答案
它将当前类的成员(m_sEmail
、m_sName
等)作为字节数组序列化到fldAttach
数据库字段中。每个数据元素都以它的大小为前缀,这就是为什么写出的每条数据都有代码 LngToByteArray(nSize)
。
在 C# 中,您将使用 MemoryStream
和 BinaryWriter
来完成它的序列化方面,然后将字节数组从内存流写入数据库.比如:
byte[] byData;
using (MemoryStream oStream = new MemoryStream)
{
using (BinaryWriter oWriter = new BinaryWriter (oStream))
{
if (m_sName == null)
{
oWriter.Write ((byte) 0); // null string
}
else
{
oWriter.Write ((byte) 1); // not a null string
oWriter.Write (m_sName);
}
// other fields
}
byData = oStream.ToArray (); // get serialized byte array
}
// use byData here
编辑:MarkJ 在评论中指出,这段代码编写的二进制格式与原始的 VB6 代码不同,只有类似的东西。如果现有数据库中包含由 VB6 代码编写的记录,则 C# 代码必须处理这些记录。
有两个主要区别:一是字符串的输出方式——原始的 VB6 代码不处理空字符串(VB6 中没有这样的概念)。另一个是 BinaryWriter.Write(string)
自动写入一个以长度为前缀的字符串 - 这可能与输出长度和字符串字节的 VB6 代码使用的格式相同,也可能不同. C# 可以使用以下逻辑在此处复制 VB6 代码:
...
// assuming sStr is not null
byte[] byString = Encoding.Unicode.GetBytes ( sStr );
oWriter.Write ( sStr.Length );
oWriter.Write ( byString );
C# 端口必须假定没有空字符串,否则它必须以某种方式处理这些字符串。
最好编写一个小实用程序来遍历数据库并将所有记录更新为新格式,其中字符串有一个空标记,一个长度前缀,然后是字符串字节。我个人会选择这个解决方案,因为那时新代码不必处理旧语言的怪癖。
PS:
请注意,VB6 中的 Long
映射到 C# 中的 int
。这对于处理 VB6 二进制格式的长度前缀很重要。
另外,这里有一个关于 VB6 字符串的问题的链接 - 这在移植时可能很有用:
关于vb6 - 这个 VB6 方法在做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13132884/