Как преобразовать двоичные данные в строки и обратно в Java?

StackOverflow https://stackoverflow.com/questions/20778

  •  09-06-2019
  •  | 
  •  

Вопрос

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

То, что у меня есть сейчас, это

byte[] buffer = ...; // read from file
// a few lines that prove I can process the data successfully
String element = new String(buffer);
byte[] newBuffer = element.getBytes();
// a few lines that try to process newBuffer and fail because it is not the same data anymore

Кто-нибудь знает, как преобразовать двоичный файл в строку и обратно без потери данных?

Ответил:Спасибо, Сэм.Я чувствую себя идиотом.Вчера я получил ответ на этот вопрос, потому что мой парсер SAX жаловался.По какой-то причине, когда я столкнулся с этой, казалось бы, отдельной проблемой, мне не пришло в голову, что это новый симптом той же проблемы.

РЕДАКТИРОВАТЬ:Просто для полноты картины я использовал База64 класс из Апач Коммонс Кодек пакет для решения этой проблемы.

Это было полезно?

Решение

Если вы закодируете его в base64, это превратит любые данные в безопасный текст ascii, но данные в кодировке base64 больше, чем исходные данные.

Другие советы

Строка(байт[]) обрабатывает данные как кодировку символов по умолчанию.Таким образом, способ преобразования байтов из 8-битных значений в 16-битные символы Java Unicode будет различаться не только в разных операционных системах, но даже может различаться у разных пользователей, использующих разные кодовые страницы на одном и том же компьютере!Этот конструктор годится только для декодирования одного из ваших собственных текстовых файлов.Не пытайтесь преобразовать произвольные байты в символы в Java!

Кодирование как база64 это хорошее решение.Вот как файлы передаются по SMTP (электронная почта).(Бесплатный) Апач Кодек Commons проект выполнит свою работу.

byte[] bytes = loadFile(file);          
//all chars in encoded are guaranteed to be 7-bit ASCII
byte[] encoded = Base64.encodeBase64(bytes);
String printMe = new String(encoded, "US-ASCII");
System.out.println(printMe);
byte[] decoded = Base64.decodeBase64(encoded);

Альтернативно вы можете использовать Java 6. Конвертер типов данных:

import java.io.*;
import java.nio.channels.*;
import javax.xml.bind.DatatypeConverter;

public class EncodeDecode {    
  public static void main(String[] args) throws Exception {
    File file = new File("/bin/ls");
    byte[] bytes = loadFile(file, new ByteArrayOutputStream()).toByteArray();
    String encoded = DatatypeConverter.printBase64Binary(bytes);
    System.out.println(encoded);
    byte[] decoded = DatatypeConverter.parseBase64Binary(encoded);
    // check
    for (int i = 0; i < bytes.length; i++) {
      assert bytes[i] == decoded[i];
    }
  }

  private static <T extends OutputStream> T loadFile(File file, T out)
                                                       throws IOException {
    FileChannel in = new FileInputStream(file).getChannel();
    try {
      assert in.size() == in.transferTo(0, in.size(), Channels.newChannel(out));
      return out;
    } finally {
      in.close();
    }
  }
}

Посмотрите этот вопрос, Как встроить двоичные данные в XML?Вместо преобразования byte[] в String с последующей передачей куда-либо в XML, преобразуйте byte[] в String с помощью кодировки BASE64 (в некоторых библиотеках XML есть тип, позволяющий сделать это за вас).Декодирование BASE64 происходит после получения строки из XML.

Использовать http://commons.apache.org/codec/

Ваши данные могут быть перепутаны из-за всевозможных странных ограничений набора символов и присутствия непечатаемых символов.Палка с BASE64.

Как вы создаете свой XML-документ?Если вы используете встроенные в Java классы XML, то кодирование строк должно обрабатываться за вас.

Взгляните на пакеты javax.xml и org.xml.Это то, что мы используем для создания XML-документов, и он довольно хорошо справляется со всем кодированием и декодированием строк.

---РЕДАКТИРОВАТЬ:

Хм, кажется, я неправильно понял проблему.Вы пытаетесь закодировать не обычную строку, а некоторый набор произвольных двоичных данных?В этом случае, вероятно, подойдет кодировка Base64, предложенная в предыдущем комментарии.Я считаю, что это довольно стандартный способ кодирования двоичных данных в XML.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top