Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将一个c#整数转换成一个大端字节(没有字节数组,只有一个字节)?_C#_Java_Arrays_Byte_Endianness - Fatal编程技术网

如何将一个c#整数转换成一个大端字节(没有字节数组,只有一个字节)?

如何将一个c#整数转换成一个大端字节(没有字节数组,只有一个字节)?,c#,java,arrays,byte,endianness,C#,Java,Arrays,Byte,Endianness,我当然知道这和持久性有关。我知道Java是big-endian,而C#是little-endian 我有一个Java工作程序,它向外部系统发送字符串。问题是,它们需要在表示其长度的字符串的末尾使用一个2字节的头 在这个2字节的头文件中,第一个头文件只是告诉您字符串是否超过255个字符,如果不超过,则始终为0。但第二个字节(我在C#中无法正确获得)将表示字符串的长度,如果第一个字节为0(几乎所有情况下),则表示字符串的整个长度,比如226 因此,在java中,我有一段代码,它计算头并附加原始字符串

我当然知道这和持久性有关。我知道Java是big-endian,而C#是little-endian

我有一个Java工作程序,它向外部系统发送字符串。问题是,它们需要在表示其长度的字符串的末尾使用一个2字节的头

在这个2字节的头文件中,第一个头文件只是告诉您字符串是否超过255个字符,如果不超过,则始终为0。但第二个字节(我在C#中无法正确获得)将表示字符串的长度,如果第一个字节为0(几乎所有情况下),则表示字符串的整个长度,比如226

因此,在java中,我有一段代码,它计算头并附加原始字符串,这样我们就可以发送最后一个字符串,它工作得很好:

Java工作代码段:

String iso_str = iso_buf.toString();    // This contains original string without header

int iso_len = iso_str.length();     // We need to know if it exceeds 255

int i, j;
i = (int)(iso_len / 256);           // Always 0. It would be 1 if original string bigger than 255
j = (int)(iso_len % 256);           // Length of the string (most times 226)

Integer ii = new Integer(i);
Integer jj = new Integer(j);

byte[] bmsg_0200 = new byte[iso_len + 2];   // We create an array of bytes making room for the 2 bytes header and the original string
bmsg_0200[0] = ii.byteValue();      // Header byte number one
bmsg_0200[1] = jj.byteValue();      // Header byte number two

System.arraycopy(iso_str.getBytes(), 0, bmsg_0200, 2, iso_str.length()); // Then we just copy the original string in the array after the header         

String mensaje_str = new String(bmsg_0200); // Make the whole byte array into one string to send
int tramaISOLongitud = iso.Length;  // iso contains original string without header, We need to know if it exceeds 255

int i, j;
i = (int)(tramaISOLongitud / 256);  // Always 0. It would be 1 if original string bigger than 255
j = (int)(tramaISOLongitud % 256);  // Length of the string (most times 226)            

byte[] tramaISOBytes = new byte[tramaISOLongitud + 2];  // We create an array of bytes making room for the 2 bytes header and the original string
tramaISOBytes[0] = Convert.ToByte(i);   // Header byte number one
tramaISOBytes[1] = Convert.ToByte(j);   // Header byte number two

System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
System.Array.ConstrainedCopy(encoding.GetBytes(iso), 0, tramaISOBytes, 2, tramaISOLongitud); // Then we just copy the original string in the array after the header

System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); 
string tramaISOHeader = enc.GetString(tramaISOBytes); // Make the whole byte array into one string to send
在说:bmsg_0200[1]=jj.byteValue()的部分;这是java实际获得一个有效字节值的地方(我认为当jj为226时,它将-30放在那里)。最后一个系统理解这个头,因此读取所有消息

我尝试在.NET(C#)中复制代码,我有以下代码:

C#非工作代码段:

String iso_str = iso_buf.toString();    // This contains original string without header

int iso_len = iso_str.length();     // We need to know if it exceeds 255

int i, j;
i = (int)(iso_len / 256);           // Always 0. It would be 1 if original string bigger than 255
j = (int)(iso_len % 256);           // Length of the string (most times 226)

Integer ii = new Integer(i);
Integer jj = new Integer(j);

byte[] bmsg_0200 = new byte[iso_len + 2];   // We create an array of bytes making room for the 2 bytes header and the original string
bmsg_0200[0] = ii.byteValue();      // Header byte number one
bmsg_0200[1] = jj.byteValue();      // Header byte number two

System.arraycopy(iso_str.getBytes(), 0, bmsg_0200, 2, iso_str.length()); // Then we just copy the original string in the array after the header         

String mensaje_str = new String(bmsg_0200); // Make the whole byte array into one string to send
int tramaISOLongitud = iso.Length;  // iso contains original string without header, We need to know if it exceeds 255

int i, j;
i = (int)(tramaISOLongitud / 256);  // Always 0. It would be 1 if original string bigger than 255
j = (int)(tramaISOLongitud % 256);  // Length of the string (most times 226)            

byte[] tramaISOBytes = new byte[tramaISOLongitud + 2];  // We create an array of bytes making room for the 2 bytes header and the original string
tramaISOBytes[0] = Convert.ToByte(i);   // Header byte number one
tramaISOBytes[1] = Convert.ToByte(j);   // Header byte number two

System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
System.Array.ConstrainedCopy(encoding.GetBytes(iso), 0, tramaISOBytes, 2, tramaISOLongitud); // Then we just copy the original string in the array after the header

System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); 
string tramaISOHeader = enc.GetString(tramaISOBytes); // Make the whole byte array into one string to send
最后一段代码编译了所有代码,但在tramaISOBytes[1]=Convert.ToByte(j)中获取了错误的字节;因为他是小恩迪安。因此,我尝试使用System.Net.IPAddress.HostToNetworkOrder,如下所示:

int tramaISOLongitud = iso.Length;  // iso contains original string without header, We need to know if it exceeds 255

int i, j;
i = (int)(tramaISOLongitud / 256);  // Always 0. It would be 1 if original string bigger than 255
j = (int)(tramaISOLongitud % 256);  // Length of the string (most times 226)    

int i2 = System.Net.IPAddress.HostToNetworkOrder(i);
int j2 = System.Net.IPAddress.HostToNetworkOrder(j);    

byte[] tramaISOBytes = new byte[tramaISOLongitud + 2];  // We create an array of bytes making room for the 2 bytes header and the original string
tramaISOBytes[0] = Convert.ToByte(i2);  // Header byte number one
tramaISOBytes[1] = Convert.ToByte(j2);  // Header byte number two

System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
System.Array.ConstrainedCopy(encoding.GetBytes(iso), 0, tramaISOBytes, 2, tramaISOLongitud); // Then we just copy the original string in the array after the header

System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); 
string tramaISOHeader = enc.GetString(tramaISOBytes); // Make the whole byte array into one string to send
但是j2得到了一个巨大的数字(比如-503316480),无法转换成单个字节,因为它太大了,而且我确实需要它放在一个字节中,因为正如我所说的,头只有2个字节长。有什么想法吗

提前谢谢


好的,我将用一种更简单的方式来解释:

在C#中:

如果我们运行这些线路,我们会得到: b=80 b2=0 b3=0

那么,为什么将数字-10471344转换为一个(字节)得到80;其他的只给0?实际上,我对变量test2=-503316480感兴趣,我希望它转换成其他形式,得到0。为什么b可以是80,而其他的不能是与0不同的东西


解决方案:正如Jim所说,我的问题与endianness无关(尽管我认为这与endianness有关),但关键知识是在.NET世界中,将字符串转换为字节数组没有问题,但是从字节数组返回到字符串是有问题的,因为您必须使用编码(ascienceoding或UTF8Enconding)这就是由于字节被损坏而出现问题的地方

在java中,我没有这种问题

这就是完成这项工作的代码块:

static byte[] addHeader2(string iso)
{
    int tramaISOLongitud = iso.Length;

    byte highByte = (byte)(tramaISOLongitud >> 8);
    byte lowByte = (byte)(tramaISOLongitud & 255);

    byte[] tramaISOBytes = new byte[tramaISOLongitud + 2];
    tramaISOBytes[0] = highByte;
    tramaISOBytes[1] = lowByte;

    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
    System.Array.ConstrainedCopy(encoding.GetBytes(iso), 0, tramaISOBytes, 2, tramaISOLongitud);

    return tramaISOBytes;
}
我只是通过套接字按原样发送字节数组


感谢大家的帮助!

将2个字节复制到一个字节数组中,并尝试将字节转换为ushort:

bool remoteSystemIsLittleEndian = false;
byte[] stringLengthBytes = new byte[] { 1, 255 };

if (BitConverter.IsLittleEndian != remoteSystemIsLittleEndian)
{
    Array.Reverse(stringLengthBytes);
}

int stringLength = (int)BitConverter.ToUInt16(stringLengthBytes, 0);
这用于将数字转换回2字节数组:

bool remoteSystemIsLittleEndian = false;
int stringLength = 511;

byte[] stringLengthBytes = BitConverter.GetBytes((ushort)stringLength);

if (BitConverter.IsLittleEndian != remoteSystemIsLittleEndian)
{
    Array.Reverse(stringLengthBytes);
}

你的问题与endian无关。当你做算术时,不管系统是big endian还是little indian。也就是说,考虑到以下情况:

int len = 260;

byte highByte = (byte)(len >> 8);
byte lowByte = (byte)(len & 255);

Console.WriteLine("highByte = {0:X2}", highByte);
Console.WriteLine("lowByte = {0:X2}", lowByte);
highByte
将始终为1,
lowByte
将始终为4

无需执行HostToNetWorkOrder转换

现在,如果你在处理负值,除法和mod运算符会给你带来意想不到的结果。但是你说它是一个2字节长的值,你存储在int中,所以负值应该不会给你带来问题

我认为,如果您单步执行原始C#代码,您将看到正确的值存储在
tramaISOBytes
数组的前两个位置。我怀疑当您尝试将生成的字节数组转换为字符串时会出现问题。您正在使用
ascienceoding
将字节数组转换为字符串,而ch将损坏大于127(0x7Fh)的任何字节

因此,您的转换不是:

System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
string tramaISOHeader = enc.GetString(tramaISOBytes);

您需要使用8位编码。可能是类似ISO-8859-2的编码。基本上,您需要的是不会尝试进行任何转换的编码。或者,更好的是,如果您将这些编码放在一起进行传输,您甚至不应该将其转换回字符串。只需直接传输字节数组。这样就不会出现任何问题。

C如果字符串为256-511个字符,则确认第一个字节为1;如果512-767 etcJava本身不是endianness,则确认第一个字节为2。我认为,尽管输出流实现可能是……如果原始字符串为226个字符:头字节1为0如果原始字符串为260个字符,则头字节2为226:头字节1为1(因为超过255)头字节2为5(原始字节与255字节之差)好吧,我可能会被误解,但你能在我的c代码中指出我该怎么做才能在一字节的big-endian中输入226个整数值吗java@Louis瓦瑟曼:你能详细解释一下为什么不是big-endian吗?Java中原语
int
中的字节存储在big-endian中。@Renexandro,强制转换为
byte
基本上是等效的取值的最低有效位8位,或与
0xFF
进行anding。区别在于
-503316480
是256的倍数,因此其最低有效位8位都是0。我刚刚尝试了您的解决方案,结果几乎与我现在使用的相同位置,即当我只有一个字节点可用如果你有4个字节,你没有使用ushort作为GetBytes的参数。如果你给它输入short或ushort以外的任何东西,它将为该类型生成一个适当长度的字节数组——除非你第一次强制转换为short或ushort。修改后的答案用int来演示。对于编码部分,你需要使用System.Te吗UTF8Encoding可以工作吗?不过,我将尝试只发送字节数组,但我认为最后我需要对该方法使用编码: