Подтвердить что ты не робот

Байт байта Java содержит отрицательные числа

Я читаю файл в байтовый массив в кусках и отправляю его по сети через запрос POST на веб-сервер. Это не что-то сложное, я сделал это, прежде чем использовать этот точный код. На этот раз я заметил, что мои образы выглядят действительно странно, когда они добираются до сервера, поэтому я решил посмотреть на отправленный массив байтов и тот, который был получен, чтобы убедиться, что он был тем же. Не это. На стороне отправки java массив байтов содержит отрицательные числа. На стороне приема С# нет отрицательных чисел.

Первые 15 байт на принимающей стороне (С#)

137
80
78
71
13
10
26
10
0
0
0
13
73
72
68

Те же байты, но на стороне отправки (java)

-119
80
78
71
13
10
26
10
0
0
0
13
73
72
68

Все неотрицательные числа одинаковы, а -119 - не единственное отрицательное число, они все кончаются. Я заметил, что -119 и 137 отделяются друг от друга и задаются вопросом, связано ли это с этим.

Код, который я использую для чтения изображения (java)

public static byte[] readPart(String fileName, long offset, int length) throws FileNotFoundException, Exception
{
    byte[] data = new byte[length];
    File file = new File(fileName);
    InputStream is = new FileInputStream(file);
    is.skip(offset);
    is.read(data,0,data.length);
    is.close();
    return data;
}

Код, который я использую для записи данных (С#)

    private void writeFile(string fileName, Stream contents)
    {
        using (FileStream fs = new FileStream(fileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite))
        {
            int bufferLen = 65000;
            byte[] buffer = new byte[bufferLen];
            int count = 0;
            while ((count = contents.Read(buffer, 0, bufferLen)) > 0)
            {
                fs.Write(buffer, 0, count);
            }
            fs.Close();
        }
        contents.Close();
    }

Я не знаю, что это то, что всегда происходит, и я просто никогда не замечал этого раньше или это то, что решило пойти ужасно неправильно. Я знаю, что этот код работал раньше для чего-то очень похожего и что он не работает сейчас.

Если у кого-то есть предложения или объяснения, я бы очень признателен.

EDIT: Причина, по которой мои изображения выглядели странно, заключается в том, как я вызывал метод readPart.

byte[] data = FileUtilities.readPart(fileName,counter,maxFileSize);//counter is the current chunk number

Как я должен был его назвать

byte[] data = FileUtilities.readPart(fileName,counter*maxFileSize,maxFileSize);//the current chunk * cuhnksize for the offset...

Спасибо всем, меня значительно меньше путают сейчас:)

4b9b3361

Ответ 1

Java не имеет неподписанных байтов; все байты считаются подписанными. Это все.

Все, что действительно имеет значение, это то, как вы думаете о байтах, так как вам редко когда-либо действительно нужно делать сравнения на байтах. Единственное существенное отличие состоит в том, что они распечатываются как подписанные, как вы обнаружили.

Если вам нравится, вы можете использовать, например, Guava UnsignedBytes утилиты для просмотра байтов Java как неподписанных, но практических отличий не так много.

Ответ 2

В Java byte представляет собой подписанное значение (используя два дополнения для кодирования отрицательных значений), так что вы видите его правильным, если это неожиданно для большинства людей.

Чтобы преобразовать значение byte в значение без знака int, используйте b & 0xff

Ответ 3

В качестве дополнительного объяснения предположим, что у вас 137 как байк без знака. Это представлено как:

1000 1001

Это двоичное значение, выраженное как подписанное два номера дополнения, оказывается -119. (-128 + 9)

Все значения без знакового байта над 128 будут зависеть от разницы, так как самый левый бит используется таким образом по двум схемам комплемента.

Ответ 4

Возможно, это связано с тем, что байт Java подписан (диапазон от -128 до 127), а С# - без знака (от 0 до 255):). Информация в двоичном формате одинакова, она просто интерпретируется по-разному.

Ответ 5

Диапазон байтов от -128 до 127, поэтому, если вы попытаетесь назначить байт 128, он будет циклически повторяться, и в результате будет -128.

System.out.println("Max val = " + Byte.MAX_VALUE);   //prints: Max val = 127
System.out.println("Min val = " + Byte.MIN_VALUE);   //prints: Min val = -128

System.out.println("(byte)137 = " + (byte)137);      //prints: (byte)137 = -119
System.out.println("(byte)128 = " + (byte)128);      //prints: (byte)128 = -128
System.out.println("(byte)-129 = " + (byte)-129);    //prints: (byte)-129 = 127