C# 从VB6字符串数据到.NET字节数组的转换

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

我正在编写一个C#应用程序,它从VB6代码生成的SQL数据库中读取数据。数据是一个单数数组。我正在尝试将它们转换为一个float[]

以下是在数据库中写入数据的VB6代码(无法更改此代码):

如您所见,数据被放入一个临时文件中,然后作为VB6字符串读回并写入数据库(dbLongBinary类型的行)

我尝试了以下方法:

做区块复制

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;
}