C# 从VB6字符串数据到.NET字节数组的转换
我正在编写一个C#应用程序,它从VB6代码生成的SQL数据库中读取数据。数据是一个单数数组。我正在尝试将它们转换为一个float[] 以下是在数据库中写入数据的VB6代码(无法更改此代码): 如您所见,数据被放入一个临时文件中,然后作为VB6字符串读回并写入数据库(dbLongBinary类型的行) 我尝试了以下方法: 做区块复制C# 从VB6字符串数据到.NET字节数组的转换,c#,.net,vb.net,vb6,C#,.net,Vb.net,Vb6,我正在编写一个C#应用程序,它从VB6代码生成的SQL数据库中读取数据。数据是一个单数数组。我正在尝试将它们转换为一个float[] 以下是在数据库中写入数据的VB6代码(无法更改此代码): 如您所见,数据被放入一个临时文件中,然后作为VB6字符串读回并写入数据库(dbLongBinary类型的行) 我尝试了以下方法: 做区块复制 byte[] source = databaseValue as byte[]; float [,] destination = new float[BitConve
byte[] source = databaseValue as byte[];
float [,] destination = new float[BitConverter.ToInt32(source, 0), BitConverter.ToInt32(source, 4)];
Buffer.BlockCopy(source, 8, destination, 0, 50 * 99 * 4);
这里的问题是VB6二进制到字符串的转换。VB6字符串字符有2个字节宽,我不知道如何将其转换回我可以处理的二进制格式
下面是VB6代码生成的临时文件的转储:
这是我从数据库中读取数据时的转储(=VB6字符串):
您能否澄清文件的内容(例如示例)?是二进制(可能是十六进制)还是字符?如果数据是VB6字符串,则必须使用float.Parse()读取。NET字符串也是每个字符2个字节,但是从文件加载时,您可以使用
编码来控制它。您能否澄清文件的内容(例如,示例)?是二进制(可能是十六进制)还是字符?如果数据是VB6字符串,则必须使用float.Parse()读取。NET字符串也是每个字符2个字节,但是从文件加载时,您可以使用编码来控制它,您可能知道,这在VB6端是非常糟糕的编码。它试图做的是将单个数据(与C#中的float相同)转换为字符串。但是,尽管有更好的方法可以做到这一点,但从一开始就不是一个好主意
主要原因是,将二进制数据读入VB6 BSTR将使用当前代码页上的命令将数据从8位字节转换为16位字符。因此,这可能会在数据库中产生不同的结果,这取决于它运行在哪个语言环境中。(!)
因此,当您从DB读回它时,除非您指定了编写时使用的相同代码页,否则您将得到不同的浮点值,甚至可能是无效的浮点值
查看二进制(single)和DB(string)格式的十六进制数据示例将有助于验证正在发生的情况
从后面的帖子:
实际上,这不是“坏”的VB6代码
这是因为它将二进制数据带入字符串域,这违反了现代VB编码的基本规则。这就是字节数据类型存在的原因。如果忽略这一点,当创建的数据库跨越区域设置边界时,很可能会产生无法识别的数据
他正在做的是存储阵列
以紧凑的二进制格式保存
将其作为“块”输入数据库。
有很多正当的理由可以这样做
这个
当然,他有一个合理的理由想要这样做(尽管你对“契约”的定义不同于传统的定义)。目的是好的:选择的手段不是
致OP:
您可能无法更改作为输入数据提供的内容,因此上述内容主要是学术性的。如果仍然有时间更改用于创建blob的方法,那么让我们建议不涉及字符串的方法
在应用任何提供的解决方案时,请尽量避免使用字符串,如果不能,请使用与创建字符串的代码页匹配的特定代码页对其进行解码。您可能知道,在VB6端进行编码是非常糟糕的。它试图做的是将单个数据(与C#中的float相同)转换为字符串。但是,尽管有更好的方法可以做到这一点,但从一开始就不是一个好主意
主要原因是,将二进制数据读入VB6 BSTR将使用当前代码页上的命令将数据从8位字节转换为16位字符。因此,这可能会在数据库中产生不同的结果,这取决于它运行在哪个语言环境中。(!)
因此,当您从DB读回它时,除非您指定了编写时使用的相同代码页,否则您将得到不同的浮点值,甚至可能是无效的浮点值
查看二进制(single)和DB(string)格式的十六进制数据示例将有助于验证正在发生的情况
从后面的帖子:
实际上,这不是“坏”的VB6代码
这是因为它将二进制数据带入字符串域,这违反了现代VB编码的基本规则。这就是字节数据类型存在的原因。如果忽略这一点,当创建的数据库跨越区域设置边界时,很可能会产生无法识别的数据
他正在做的是存储阵列
以紧凑的二进制格式保存
将其作为“块”输入数据库。
有很多正当的理由可以这样做
这个
当然,他有一个合理的理由想要这样做(尽管你对“契约”的定义不同于传统的定义)。目的是好的:选择的手段不是
致OP:
您可能无法更改作为输入数据提供的内容,因此上述内容主要是学术性的。如果仍然有时间更改用于创建blob的方法,那么让我们建议不涉及字符串的方法
在应用任何提供的解决方案时,请尽量避免使用字符串,如果无法避免,请使用与创建字符串的代码页匹配的特定代码页对其进行解码。实际上,这不是“坏”的VB6代码。他所做的是以紧凑的二进制格式存储数组,并将其作为“块”保存到数据库中。这样做有很多正当的理由
VB6代码将其保存到磁盘并将其读回的原因是VB6本身不支持仅在内存中读取和写入文件。如果您想创建一个二进制数据块并将其填充到其他地方(如数据库字段),这是常用的算法
在.NET中处理这个问题不是一个问题。我的代码在VB.NET中,因此您必须将其转换为C
修改为处理字节和unicode问题
Public Function DataArrayFromDatabase(ByVal dbData As byte()) As Single(,)
Dim bData(Ubound(dbData)/2) As Byte
Dim I As Long
Dim J As Long
J=0
For I = 1 To Ubound(dbData) step 2
bData(J) = dbData(I)
J=1
Next I
Dim sM As New IO.MemoryStream(bData)
Dim bR As IO.BinaryReader = New IO.BinaryReader(sM)
Dim Dim1 As Integer = bR.ReadInt32
Dim Dim2 As Integer = bR.ReadInt32
Dim newData(Dim1, Dim2) As Single
For I = 0 To Dim2
For J = 0 To Dim1
newData(J, I) = bR.ReadSingle
Next
Next
bR.Close()
sM.Close()
Return newData
End Function
钥匙
Public Function DataArrayFromDatabase(ByVal dbData As byte()) As Single(,)
Dim bData(Ubound(dbData)/2) As Byte
Dim I As Long
Dim J As Long
J=0
For I = 1 To Ubound(dbData) step 2
bData(J) = dbData(I)
J=1
Next I
Dim sM As New IO.MemoryStream(bData)
Dim bR As IO.BinaryReader = New IO.BinaryReader(sM)
Dim Dim1 As Integer = bR.ReadInt32
Dim Dim2 As Integer = bR.ReadInt32
Dim newData(Dim1, Dim2) As Single
For I = 0 To Dim2
For J = 0 To Dim1
newData(J, I) = bR.ReadSingle
Next
Next
bR.Close()
sM.Close()
Return newData
End Function
char[] destinationAsChars = new char[BitConverter.ToInt32(source, 0)* BitConverter.ToInt32(source, 4)];
byte[] asciiBytes = Encoding.ASCII.GetBytes(destinationAsChars);
float[] destination = new float[notSureHowLarge];
Buffer.BlockCopy(asciiBytes, 0, destination, 0, asciiBytes.Length);
internal void FixBytes()
{
//Convert the bytes from VB6 style BSTR to standard byte[].
char[] destinationAsChars =
System.Text.Encoding.Unicode.GetString(File).ToCharArray();
byte[] asciiBytes = Encoding.Default.GetBytes(destinationAsChars);
byte[] newFile = new byte[asciiBytes.Length];
Buffer.BlockCopy(asciiBytes,0, newFile, 0, asciiBytes.Length);
File = newFile;
}