簡體   English   中英

在無符號字節變量中表示有符號字節

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM