Я читаю файл в массив байтов фрагментами и отправляю его по сети с помощью 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...
Спасибо всем, теперь я значительно меньше запутался :)
В Java byte
- это значение со знаком (с использованием дополнения к двум для кодирования отрицательных значений), так что, как вы видите, это правильно, если большинство людей неожиданно.
Чтобы преобразовать byte
в значение без знака int
, используйте b & 0xff
Возможно, это как-то связано с тем, что байт Java подписан (в диапазоне от -128 до 127), а C # - без знака (от 0 до 255) :). Информация в двоичном коде одинакова, просто она интерпретируется по-разному.
Диапазон байта от-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