Ну, причина в том, что привязки выполняются при выполнении кода, и выполняется определение функции, ну ... когда функции определены.
Сравните это:
class BananaBunch:
bananas = []
def addBanana(self, banana):
self.bananas.append(banana)
Этот код страдает от такого же неожиданного случая. bananas - это атрибут класса, и, следовательно, когда вы добавляете к нему вещи, он добавляется ко всем экземплярам этого класса. Причина в том, что это точно то же самое.
Это просто «Как это работает», и заставить его работать по-другому в функциональном случае, вероятно, будет сложно, а в случае класса вероятно невозможно или, по крайней мере, замедлить объект создание экземпляра, так как вам придется хранить код класса и выполнять его при создании объектов.
Да, это неожиданно. Но как только пенни падает, она прекрасно вписывается в то, как работает Python в целом. На самом деле, это хорошее учебное пособие, и как только вы поймете, почему это происходит, вы будете намного лучше читать python.
Это говорит о том, что он должен занимать видное место в любом хорошем учебнике Python. Потому что, как вы говорите, все рано или поздно сталкиваются с этой проблемой.
Вы не можете просто взять возвращаемую строку и построить из нее строку ... это больше не тип данных byte[]
, это уже строка; вам нужно разобрать его. Например:
String response = "[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]"; // response from the Python script
String[] byteValues = response.substring(1, response.length() - 1).split(",");
byte[] bytes = new byte[byteValues.length];
for (int i=0, len=bytes.length; i<len; i++) {
bytes[i] = Byte.parseByte(byteValues[i].trim());
}
String str = new String(bytes);
** РЕДАКТИРОВАТЬ **
Вы получаете намек на свою проблему в своем вопросе, где вы говорите «Whatever I seem to try I end up getting a byte array which looks as follows... [91, 45, ...
», потому что 91
значение байта для [
, поэтому [91, 45, ...
является байтовым массивом строки «[-45, 1, 16, ...
».
Метод Arrays.toString()
вернет представление String
указанного массива; что возвращаемое значение больше не будет массивом. Например:
byte[] b1 = new byte[] {97, 98, 99};
String s1 = Arrays.toString(b1);
String s2 = new String(b1);
System.out.println(s1); // -> "[97, 98, 99]"
System.out.println(s2); // -> "abc";
Как вы можете видеть, s1
содержит строковое представление массива b1
, а s2
содержит строковое представление байтов, содержащихся в b1
.
Теперь, в вашей проблеме, ваш сервер возвращает строку, похожую на s1
, поэтому, чтобы вернуть представление массива назад, вам нужен противоположный метод конструктора. Если s2.getBytes()
противоположно new String(b1)
, вам нужно найти противоположность Arrays.toString(b1)
, таким образом, код, который был вставлен в первый фрагмент этого ответа.
Используйте приведенный ниже API кода для преобразования байт-кода в виде строки в массив байтов.
byte[] byteArray = DatatypeConverter.parseBase64Binary("JVBERi0xLjQKMyAwIG9iago8P...");
Если вы хотите преобразовать строку обратно в массив байтов, вам нужно будет использовать функцию String.getBytes()
(или эквивалентную функцию Python), и это позволит вам распечатать исходный массив байтов.
String coolString = "cool string";
byte[] byteArray = coolString.getBytes();
String reconstitutedString = new String(byteArray);
System.out.println(reconstitutedString);
Это выводит «прохладную строку» на консоль.
Это довольно прост.
byte[]
он представлен как String
; т.е. "[97, 98, 99]"
не [97, 98, 99]
. Смысл, ваш ответ даже не относится к этой ситуации.
– b1nary.atr0phy
5 June 2013 в 17:30
String
- byte[]
- String
. Я думаю, что требование вопроса - byte[]
- String
- byte[]
.
– Wundwin Born
9 May 2014 в 17:22
Простое преобразование байтового массива в строку и строку обратно в байтовый массив в java. нам нужно знать, когда правильно использовать «новое». Это можно сделать следующим образом:
массив байтов для преобразования строк:
byte[] bytes = initializeByteArray();
String str = new String(bytes);
Преобразование строк в байтовый массив:
String str = "Hello"
byte[] bytes = str.getBytes();
Для получения дополнительной информации, посмотрите на: http://evverythingatonce.blogspot.in/2014/01/tech-talkbyte-array-and-string.html
Не можете ли вы просто отправить байты в виде байтов или преобразовать каждый байт в символ и отправить в виде строки? Выполнение этого, как и вы, займет не менее 85 символов в строке, если у вас есть только 11 байтов для отправки. Вы можете создать строковое представление байтов, поэтому это будет «[B @ 405217f8», который может быть легко преобразован в объект bytes
или bytearray
в Python. В противном случае вы можете представить их как последовательность шестнадцатеричных цифр («5b42403430353231376638»), занимающих 22 символа, которые могут быть легко декодированы на стороне Python с помощью binascii.unhexlify()
.
[B@405217f8
является идентификатором объекта Java массива, а не содержимым массива. Идентификатор объекта, конечно, не может i> & quot; легко преобразовать в байты или объект bytearray в python & quot ;. Лучшее, что вы можете сделать по размеру, это преобразовать байт [] в строку base64.
– Boris B.
23 November 2012 в 11:57
Вид вывода, который вы видите из вашего байтового массива ([B@405217f8
), также является выходным для массива байтов с нулевой длиной (например, new byte[0]
). Похоже, что эта строка является ссылкой на массив, а не описанием содержимого массива, как мы могли бы ожидать из метода toString()
регулярной коллекции.
Как и в случае с другими респондентами, я хотел бы указать вам к конструкторам String
, которые принимают параметр byte[]
для построения строки из содержимого массива байтов. Вы должны иметь возможность читать необработанные байты из InputStream
сокета, если вы хотите получить байты из TCP-соединения.
Если вы уже прочитали эти байты как String
(используя InputStreamReader
), тогда строка может быть преобразована в байты с помощью функции getBytes()
. Обязательно передайте желаемый набор символов как для конструктора String, так и для функций getBytes()
, и это будет работать, только если данные байта могут быть преобразованы в символы с помощью InputStreamReader
.
Если вы хотите иметь дело с необработанными байтами, вы действительно должны избегать использования этого слоя чтения потока.
Что я сделал:
вернуться к клиентам:
byte[] result = ****encrypted data****;
String str = Base64.encodeBase64String(result);
return str;
получать от клиентов:
byte[] bytes = Base64.decodeBase64(str);
ваши данные будут перенесены в этом формате :
OpfyN9paAouZ2Pw+gDgGsDWzjIphmaZbUyFx5oRIN1kkQ1tDbgoi84dRfklf1OZVdpAV7TonlTDHBOr93EXIEBoY1vuQnKXaG+CJyIfrCWbEENJ0gOVBr9W3OlFcGsZW5Cf9uirSmx/JLLxTrejZzbgq3lpToYc3vkyPy5Y/oFWYljy/3OcC/S458uZFOc/FfDqWGtT9pTUdxLDOwQ6EMe0oJBlMXm8J2tGnRja4F/aVHfQddha2nUMi6zlvAm8i9KnsWmQG//ok25EHDbrFBP2Ia/6Bx/SGS4skk/0couKwcPVXtTq8qpNh/aYK1mclg7TBKHfF+DHppwd30VULpA==
[JAVA 8]
import java.util.Base64;
String dummy= "dummy string";
byte[] byteArray = dummy.getBytes();
byte[] salt = new byte[]{ -47, 1, 16, ... }
String encoded = Base64.getEncoder().encodeToString(salt);
То, что Arrays.toString()
делает, создает строковое представление каждого отдельного байта в вашем byteArray.
Пожалуйста, проверьте документацию API API массивов
To преобразуйте строку ответа обратно в исходный массив байтов, вы должны использовать split(",")
или что-то другое и преобразовать его в коллекцию, а затем преобразовать каждый отдельный элемент в байт, чтобы воссоздать ваш массив байтов.
response
в моем ответе, а, к сожалению, нет другого пути. Лучшим способом было бы получить байты как необработанные данные (как двоичные) вместо строки или, возможно, даже в качестве строки Base64, которая потребовала бы только вернуть ее в качестве базового 256 (двоичного) значения. – Yanick Rochon 4 February 2013 в 19:06