[英]Representing signed byte in an unsigned byte variable
如果這個問題的標題不清楚,我深表歉意,但是我無法找出用這么幾個詞來描述我的困境的最佳方法。
我正在使用套接字和逐字節信息傳遞來編寫Java和C#之間的通信框架。
我遇到了一個困擾了我好幾個小時的問題。 如您所願。 java的字節基類型是帶符號的,這意味着如果要以整數形式表示它,則它可以存儲-128到+127。 但是,C#使用無符號字節,這意味着它以整數形式存儲0-255。
這是我遇到的問題。 如果需要從C#客戶端向Java服務器發送一些字節的信息,我使用以下代碼:
C#:
MemoryStream stream;
public void write(byte[] b, int off, int len) {
stream.Write(b, off, len);
}
Java的:
DataInputStream in;
public int read(byte[] b, int off, int len) throws IOException{
in.read(b, off, len));
}
如您所見,這些是非常相似的代碼片段,當以其自己的語言使用時,它們會產生可預測的結果。 但是,由於簽名上的差異,這些將產生無法使用的數據。
即如果我從我的C#客戶端向Java服務器發送255,我將在Java服務器上收到值-1。 這是因為這兩個值均由以下8位表示:11111111
最好為了解決這個問題,我需要使用以下代碼,使用sbyte
,即c#的帶符號字節。
C#:
MemoryStream stream;
public void write(sbyte[] b, int off, int len) {
//Code to change sbyte into a byte but keeping it in the form in which java will understand
stream.Write(b, off, len);
}
我基本上需要將Java的一個有符號字節表示形式存儲在一個無符號C#字節中,以便將該字節發送到服務器。 我還需要反向執行此操作,以從Java服務器接收的字節中提取一個字節。
我嘗試了許多方法來完成此操作,但均未成功。 如果有人對我該如何做有任何想法,我將非常感激。
除了停止將字節視為數字外,您基本上不需要執行任何操作。 將它們視為8位,並且Java和C#是相同的。 真正將字節視為大小的情況很少見-它通常只是二進制數據(例如圖像)或編碼文本。
如果要將字節10100011從Java發送到C#,反之亦然,則以最自然的方式執行。 即使將字節視為數字時字節值不同,這些位也將是正確的。
尚不清楚您實際上試圖傳播哪些數據,但是在99.9%的情況下,您可以將byte[]
視為不透明的二進制數據,然后進行傳輸而不必擔心。
如果確實需要將字節視為大小,則需要確定所需的范圍。 處理Java范圍更容易,因為C#可以使用sbyte[]
支持它。但是,如果您希望范圍為0-255,則只需要在Java端將byte
轉換為int
並用底部對其進行掩碼即可8位:
byte b = ...;
int unsigned = b & 0xff;
如果確實需要在C#上將byte[]
視為sbyte[]
或反之亦然,則可以使用一個小秘密:即使C#不允許您在兩者之間進行轉換,CLR也會這樣做。 您需要做的就是通過將引用轉換為object
來欺騙C#編譯器,使其認為它可能是有效的-否則,它認為它最了解。 因此,這毫無例外地執行:
byte[] x = new byte[] { 255 };
sbyte[] y = (sbyte[]) (object) x;
Console.WriteLine(y[0]); // -1
您可以以完全相同的方式在另一個方向上進行轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.