Byte Visual Studio C++;2008字节?

Byte Visual Studio C++;2008字节?,byte,writing,Byte,Writing,我试图将严格的二进制数据写入文件(无编码)。问题是,当我转储文件时,我注意到相当奇怪的行为。使用以下任一方法构造文件都会导致相同的行为。我甚至还使用System::Text::Encoding::Default来测试流 StreamWriter^ binWriter = gcnew StreamWriter(gcnew FileStream("test.bin",FileMode::Create)); (Also used this method) FileStream^ tempBin =

我试图将严格的二进制数据写入文件(无编码)。问题是,当我转储文件时,我注意到相当奇怪的行为。使用以下任一方法构造文件都会导致相同的行为。我甚至还使用System::Text::Encoding::Default来测试流

StreamWriter^ binWriter = gcnew StreamWriter(gcnew FileStream("test.bin",FileMode::Create));

(Also used this method)
FileStream^ tempBin = gcnew FileStream("test.bin",FileMode::Create);
BinaryWriter^ binWriter = gcnew BinaryWriter(tempBin);


binWriter->Write(0x80);
binWriter->Write(0x81);
.
.
binWriter->Write(0x8F);
binWriter->Write(0x90);
binWriter->Write(0x91);
.
.
binWriter->Write(0x9F);
在写那个字节序列时,我注意到在十六进制转储中唯一没有转换为0x3F的字节是0x81,0x8D,0x90,0x9D。。。我不知道为什么

我还尝试制作角色数组,类似的情况也发生了。i、 e

array<wchar_t,1>^ OT_Random_Delta_Limits = {0x00,0x00,0x03,0x79,0x00,0x00,0x04,0x88};
binWriter->Write(OT_Random_Delta_Limits);
数组^OT_Random_Delta_Limits={0x00,0x00,0x03,0x79,0x00,0x00,0x04,0x88};
binWriter->Write(随机增量限制);
0x88将被写入0x3F


有什么想法吗?

如果你想坚持使用二进制文件,那么不要使用
StreamWriter
。只需使用
FileStream
Write
/
WriteByte
。StreamWriter(通常也包括TextWriter)是专为文本而设计的。无论您是否需要编码,都会应用一种编码,因为当您调用
StreamWriter.Write
时,这是在写
char
,而不是
byte

也不要创建
wchar\u t
值的数组-同样,这些数组用于字符,即文本

BinaryWriter.Write
应该对您有效,除非它将值提升为
char
,在这种情况下,您会遇到完全相同的问题

顺便说一下,在不指定任何编码的情况下,我希望您获得非0x3F值,而是表示这些字符的UTF-8编码值的字节

当您指定
编码.Default
时,您会看到任何不在该编码中的Unicode值的0x3F

无论如何,基本的经验是,当您想处理二进制数据而不是文本时,要坚持使用
Stream

编辑:好的,它会是这样的:

public static void ConvertHex(TextReader input, Stream output)
{
    while (true)
    {
        int firstNybble = input.Read();
        if (firstNybble == -1)
        {
            return;
        }
        int secondNybble = input.Read();
        if (secondNybble == -1)
        {
            throw new IOException("Reader finished half way through a byte");
        }
        int value = (ParseNybble(firstNybble) << 4) + ParseNybble(secondNybble);
        output.WriteByte((byte) value);
    }
}

// value would actually be a char, but as we've got an int in the above code,
// it just makes things a bit easier
private static int ParseNybble(int value)
{
    if (value >= '0' && value <= '9') return value - '0';
    if (value >= 'A' && value <= 'F') return value - 'A' + 10;
    if (value >= 'a' && value <= 'f') return value - 'a' + 10;
    throw new ArgumentException("Invalid nybble: " + (char) value);
}
publicstaticvoidconvertHex(文本阅读器输入,流输出)
{
while(true)
{
int firstNybble=input.Read();
if(firstnyble==-1)
{
返回;
}
int secondNybble=input.Read();
if(secondnyble==-1)
{
抛出新IOException(“读卡器完成了一个字节的一半”);
}

int value=(parsenyble(firstnyble)如果您想坚持使用二进制文件,那么不要使用
StreamWriter
。只需使用
FileStream
Write
/
WriteByte
。StreamWriter(通常包括文本编写器)是专门为文本而设计的。无论您是否需要编码,都会应用一种编码,因为当您调用
StreamWriter.Write
时,这是在写
char
,而不是
字节

也不要创建
wchar\u t
值的数组-同样,这些数组用于字符,即文本

BinaryWriter.Write
应该对您有效,除非它将值提升为
char
,在这种情况下,您会遇到完全相同的问题

顺便说一下,在不指定任何编码的情况下,我希望您获得非0x3F值,而是表示这些字符的UTF-8编码值的字节

当您指定
编码.Default
时,您会看到任何不在该编码中的Unicode值的0x3F

无论如何,基本的经验是,当您想处理二进制数据而不是文本时,要坚持使用
Stream

编辑:好的,它会是这样的:

public static void ConvertHex(TextReader input, Stream output)
{
    while (true)
    {
        int firstNybble = input.Read();
        if (firstNybble == -1)
        {
            return;
        }
        int secondNybble = input.Read();
        if (secondNybble == -1)
        {
            throw new IOException("Reader finished half way through a byte");
        }
        int value = (ParseNybble(firstNybble) << 4) + ParseNybble(secondNybble);
        output.WriteByte((byte) value);
    }
}

// value would actually be a char, but as we've got an int in the above code,
// it just makes things a bit easier
private static int ParseNybble(int value)
{
    if (value >= '0' && value <= '9') return value - '0';
    if (value >= 'A' && value <= 'F') return value - 'A' + 10;
    if (value >= 'a' && value <= 'f') return value - 'a' + 10;
    throw new ArgumentException("Invalid nybble: " + (char) value);
}
publicstaticvoidconvertHex(文本阅读器输入,流输出)
{
while(true)
{
int firstNybble=input.Read();
if(firstnyble==-1)
{
返回;
}
int secondNybble=input.Read();
if(secondnyble==-1)
{
抛出新IOException(“读卡器完成了一个字节的一半”);
}

int value=(parsenyble(firstnyble)0x3F通常被称为ASCII字符“?”;映射到它的字符是没有可打印表示的控制字符。正如Jon指出的,对于原始二进制数据,使用二进制流而不是面向文本的输出机制


编辑——实际上,您的结果与我预期的结果相反。默认情况下,不可打印的字符(即可能映射到“?”的字符)在这个范围内是0x81、0x8D、0x8F、0x90和0x9D

0x3F通常被称为ASCII字符“?”;映射到它的字符是没有可打印表示的控制字符。正如Jon指出的,对原始二进制数据使用二进制流而不是面向文本的输出机制

编辑——实际上,您的结果与我的预期相反。默认情况下,该范围内的不可打印字符(即可能映射到“?”)为0x81、0x8D、0x8F、0x90和0x9D
用流初始化的类将对写入的任何字符或字符串使用默认的UTF8编码

binWriter->Write(0x80);
binWriter->Write(0x81);
.
.
binWriter->Write(0x8F);
binWriter->Write(0x90);
binWriter->Write(0x91);
调用绑定到
Write(char)
重载,因此它们要经过字符编码器。我对C++/CLI不是很熟悉,但在我看来,这些调用应该绑定到
Write(Int32)
,这不应该有这个问题(也许你的代码真的在调用
Write()
使用设置为示例中的值的
char
变量。这将解释此行为)。

使用流初始化的
BinaryWriter()
类将对写入的任何字符或字符串使用默认的UTF8编码。我猜

binWriter->Write(0x80);
binWriter->Write(0x81);
.
.
binWriter->Write(0x8F);
binWriter->Write(0x90);
binWriter->Write(0x91);
调用绑定到
Write(char)
重载,因此它们要经过字符编码器。我对C++/CLI不是很熟悉,但在我看来,这些调用应该绑定到
Write(Int32)
,w