Java байтовый массив содержит отрицательные числа - PullRequest
28 голосов
/ 08 марта 2012

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

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

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 - это 256, и подумал, что это как-то связано с этим.

Код, который я использую для чтения изображения (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;
}

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

    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();
    }

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

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

РЕДАКТИРОВАТЬ:Причина, по которой мои изображения выглядели странно, заключается в том, как я вызывал метод 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...

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

Ответы [ 4 ]

38 голосов
/ 08 марта 2012

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

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

31 голосов
/ 08 марта 2012

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

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

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

13 голосов
/ 08 марта 2012

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

1000 1001

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

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

3 голосов
/ 08 марта 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...