SQL Server VARBINARY(max) to c# byte[]

时间:2023-01-21 00:55:58

I am querying the table (one of the columns is a VARBINARY(MAX)) which returns some records.

我正在查询表(其中一列是VARBINARY(MAX)),它返回一些记录。

Then I save that as .dat.csv then I parse through that .dat file and get that varbinary value into a string by splitting the file based on commas. Now I need to convert this varbinary to byte array. How can I do that?

然后保存为。dat。然后,我解析这个.dat文件,并将这个varbinary值通过基于逗号的文件分割成一个字符串。现在我需要将这个varbinary数组转换为byte数组。我怎么做呢?

1 个解决方案

#1


5  

Good question. Technically, you can do this by first converting to a character array, then converting to bytes. However, strings in .NET are Unicode-encoded by default (instead of ASCII), so it gets tricky.

好问题。从技术上讲,您可以通过首先转换为字符数组,然后转换为字节来实现这一点。然而,. net中的字符串默认是unicode编码的(而不是ASCII),所以它变得很棘手。

If at all possible, you should try to pull the varbinary out of the file as a byte array, using the FileStream you're reading from instead of the StreamReader which performs encoding conversions to and from the file encoding type.

如果可能的话,您应该尝试将varbinary从文件中提取为一个字节数组,使用您正在读取的FileStream,而不是从文件编码类型执行编码转换的StreamReader。

The problem with this byte-to-string-to-byte babelfishing is that certain bytecodes have special meaning in each Unicode encoding, giving information to the decoder about the number of bytes it should pull to decode the next character. When converting between various Unicode encodings and the .NET-native UTF-8 encoding for strings, bytes will be gained, lost, and changed. When it's a string, no biggie; the encoding information stays with the string. When it's binary data, the encoding and decoding can garble it unless it's done in a very specific way.

这种从字节到字符串的babelfishing的问题是,某些字节码在每个Unicode编码中都有特殊的含义,它向解码器提供关于解码下一个字符所需的字节数的信息。当在各种Unicode编码和字符串的. net本机UTF-8编码之间进行转换时,将获得、丢失和更改字节。当它是字符串时,没有大问题;编码信息与字符串保持一致。当它是二进制数据时,编码和解码可以混淆它,除非它以一种非常特定的方式完成。

The only way this will work flawlessly is if you write the file out using ASCII encoding, then read it back in as such, which will cause each individual byte to be treated as a single character. You can then simply convert each char back to a byte, and the more significant byte of the UInt16 behind the scenes of the Syetem.Char, which is just zero-padding for the byte fed in to that char, will be discarded.

唯一能够完美地工作的方法是,如果您使用ASCII编码将文件写出来,然后将其读入,这将导致每个字节被视为单个字符。然后,您可以简单地将每个字符转换回一个字节,以及Syetem幕后UInt16中更重要的字节。将丢弃Char,它只是为输入到该Char的字节进行的零填充。

var reader = new StreamReader(new FileStream("test.csv"), Encoding.ASCII);
var varBinaryString = reader.Read(<wherever the varbinary is in the file/line>);

var byteArray = varBinaryString.ToCharArray().Select(c=>(byte)c).ToArray();

Technically, you could pull it in using any Unicode encoding as well, but you need to know a lot of specifics about how you wrote out those bytes and how the reader is reading them back in, so that you can perform the correct encoding and expansion (or deflation) as necessary to get the original bytestream.

从技术上讲,你可以把它在使用Unicode编码,但是你需要知道很多细节关于你写的这些字节和读者的阅读他们回去,这样你可以执行正确的编码和扩张(或通货紧缩)必要的原始bytestream。

EDIT: The .NET 2.0 version - no Linq:

编辑:。net 2.0版本-没有Linq:

StreamReader reader = new StreamReader(new FileStream("test.csv"), Encoding.ASCII);
string varBinaryString = reader.Read(<wherever the varbinary is in the file/line>);

char[] charArray = varBinaryString.ToCharArray();
byte[] byteArray = new byte[charArray.Length];

for(int i=0; i< charArray.length; i++)
{
    byteArray[i] = (byte)charArray[i];
}

#1


5  

Good question. Technically, you can do this by first converting to a character array, then converting to bytes. However, strings in .NET are Unicode-encoded by default (instead of ASCII), so it gets tricky.

好问题。从技术上讲,您可以通过首先转换为字符数组,然后转换为字节来实现这一点。然而,. net中的字符串默认是unicode编码的(而不是ASCII),所以它变得很棘手。

If at all possible, you should try to pull the varbinary out of the file as a byte array, using the FileStream you're reading from instead of the StreamReader which performs encoding conversions to and from the file encoding type.

如果可能的话,您应该尝试将varbinary从文件中提取为一个字节数组,使用您正在读取的FileStream,而不是从文件编码类型执行编码转换的StreamReader。

The problem with this byte-to-string-to-byte babelfishing is that certain bytecodes have special meaning in each Unicode encoding, giving information to the decoder about the number of bytes it should pull to decode the next character. When converting between various Unicode encodings and the .NET-native UTF-8 encoding for strings, bytes will be gained, lost, and changed. When it's a string, no biggie; the encoding information stays with the string. When it's binary data, the encoding and decoding can garble it unless it's done in a very specific way.

这种从字节到字符串的babelfishing的问题是,某些字节码在每个Unicode编码中都有特殊的含义,它向解码器提供关于解码下一个字符所需的字节数的信息。当在各种Unicode编码和字符串的. net本机UTF-8编码之间进行转换时,将获得、丢失和更改字节。当它是字符串时,没有大问题;编码信息与字符串保持一致。当它是二进制数据时,编码和解码可以混淆它,除非它以一种非常特定的方式完成。

The only way this will work flawlessly is if you write the file out using ASCII encoding, then read it back in as such, which will cause each individual byte to be treated as a single character. You can then simply convert each char back to a byte, and the more significant byte of the UInt16 behind the scenes of the Syetem.Char, which is just zero-padding for the byte fed in to that char, will be discarded.

唯一能够完美地工作的方法是,如果您使用ASCII编码将文件写出来,然后将其读入,这将导致每个字节被视为单个字符。然后,您可以简单地将每个字符转换回一个字节,以及Syetem幕后UInt16中更重要的字节。将丢弃Char,它只是为输入到该Char的字节进行的零填充。

var reader = new StreamReader(new FileStream("test.csv"), Encoding.ASCII);
var varBinaryString = reader.Read(<wherever the varbinary is in the file/line>);

var byteArray = varBinaryString.ToCharArray().Select(c=>(byte)c).ToArray();

Technically, you could pull it in using any Unicode encoding as well, but you need to know a lot of specifics about how you wrote out those bytes and how the reader is reading them back in, so that you can perform the correct encoding and expansion (or deflation) as necessary to get the original bytestream.

从技术上讲,你可以把它在使用Unicode编码,但是你需要知道很多细节关于你写的这些字节和读者的阅读他们回去,这样你可以执行正确的编码和扩张(或通货紧缩)必要的原始bytestream。

EDIT: The .NET 2.0 version - no Linq:

编辑:。net 2.0版本-没有Linq:

StreamReader reader = new StreamReader(new FileStream("test.csv"), Encoding.ASCII);
string varBinaryString = reader.Read(<wherever the varbinary is in the file/line>);

char[] charArray = varBinaryString.ToCharArray();
byte[] byteArray = new byte[charArray.Length];

for(int i=0; i< charArray.length; i++)
{
    byteArray[i] = (byte)charArray[i];
}