Строка Java из массива байтов

#java #arrays #string

#java #массивы #строка

Вопрос:

В настоящее время я читаю в массиве байтов UDP, который, как я знаю, является строкой, и я знаю МАКСИМАЛЬНО возможную длину указанной строки. Итак, я распечатываю строку (которая обычно короче максимальной длины). Я могу распечатать ее, но она выводит текст, а затем ненужные символы. Есть ли способ обрезать ненужные двоичные данные, не зная фактической длины допустимого текста?

 String result = new String(input, Charset.forName("US-ASCII"));
  

Я попробую для тех, кто запрашивает больше данных. Вот как читается сообщение UDP:

 sock.receive(incoming);
byte[] data = incoming.getData();
String s = new String(data, 0, incoming.getLength());
  

Само UDP-сообщение будет содержать заголовок фиксированного размера, а затем набор данных (максимальный размер 1024 байта). Эти данные могут быть int, string, byte и т.д. Это определяется данными заголовка. Итак, в зависимости от типа, я выделяю данные на основе фрагментов соответствующего размера. Проблема, на которой я сосредотачиваюсь, заключается в строковом типе данных. Я знаю, что максимальный размер строки будет составлять 128 байт на строку, поэтому я считываю это количество порциями через где dataArray — это массив байтов.:

 for (int i = 0; i < msg.length; i = i   readSize)
    {
        dataArray = Arrays.copyOfRange(msg, i, i   readSize);
    }
  

Затем я использую исходный код из первого набора кода в этом сообщении, чтобы поместить данные в объект string. Дело в том, что обычно отправляемый текст меньше 128 байт, выделенных для максимального размера. Итак, когда я печатаю строку, я получаю допустимый текст, а затем пробелы и ненормальные символы ascii (ненужные данные). Надеюсь, это дополнение поможет.

Пример вывода приведен здесь. Все, вплоть до .mof, допустимо:

https://1drv.ms/i/s!Ai0t7Oj1PUFBpRP9K_2RlocAK4B7

Комментарии:

1. Нам нужно больше деталей, чтобы помочь вам

2. пожалуйста, покажите нам код, в котором вы считываете поток UDP

3. Пожалуйста, опубликуйте пример вывода…

4. Похоже, вы не используете правильную кодировку, декодер входной строки.

5. Вам нужно сообщить нам кодировку строки. Многие кодировки используют более одного байта для представления символа.

Ответ №1:

Есть ли способ обрезать ненужные двоичные данные, не зная фактической длины допустимого текста?

Да, вы можете просто вызвать trim() , это удалит завершающие нулевые символы. Действительно, trim() удаляет все начальные и конечные символы, меньшие или равные u0020 (он же пробел), которые включают u0000 (он же нулевой символ).

 byte[] bytes = "foo bar".getBytes();

// Simulate message with a size bigger than the actual encoded String
byte[] msg = new byte[32];
System.arraycopy(bytes, 0, msg, 0, bytes.length);

// Decode the message
String result = new String(msg, Charset.forName("US-ASCII"));
// Trim the result
System.out.printf("Result: '%s'%n", result.trim());
  

Вывод:

 Result: 'foo bar'
  

Комментарии:

1. Это не просто пробел.

2. Нет. Я все же попробую. Но из Java API: trim() Возвращает копию строки с опущенными начальными и конечными пробелами.

3. Нет, вы неправильно поняли документ, trim удаляет каждый символ перед u0020 , который включает нулевой символ u0000

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

5. Хорошо, я попробовал trim, и это не сработало. Вот результат. Не удается скопировать и вставить, потому что не отображаются ненужные символы. Хорошая информация — это все, что находится перед файлом .mof. 1drv.ms/i/s!Ai0t7Oj1PUFBpRP9K_2RlocAK4B7

Ответ №2:

Хорошо, вот как я смог заставить это работать. Это довольно ручной метод, но перед использованием

 String result = new String(input, Charset.forName("US-ASCII"));
  

чтобы объединить массив байтов в строку, я просмотрел каждый байт и убедился, что он находится в пределах допустимого для печати диапазона 0x20 — 0x7e. Если нет, я заменил значение пробелом (0x20). Затем закончил с помощью .trim для строки.