我们正在将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
Run Code Online (Sandbox Code Playgroud)
看起来它正在做一些二进制文件复制类型的东西,但我不太了解.有人可以解释一下,我们可以重写它吗?
它当前类(成员序列化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
Run Code Online (Sandbox Code Playgroud)
编辑: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 );
Run Code Online (Sandbox Code Playgroud)
C#端口必须假定没有空字符串,否则它必须以某种方式处理它们.
编写一个通过数据库并将所有记录更新为新格式的小实用程序可能会更好,其中字符串具有空标记,长度前缀,然后是字符串字节.我个人会使用这个解决方案,因为那时新代码不必处理古老语言的怪癖.
PS:
请注意,Long在VB6中映射到intC#.这对于处理VB6二进制格式的长度前缀很重要.
此外,这里是一个关于VB6字符串的问题的链接 - 这在移植时可能很有用:
| 归档时间: |
|
| 查看次数: |
614 次 |
| 最近记录: |