Подтвердить что ты не робот

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

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

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

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

EDIT: Только для полноты я использовал Base64 класс из Apache Commons Codec пакет для решения этой проблемы.

4b9b3361

Ответ 1

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

Ответ 2

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

Кодирование как base64 является хорошим решением. Так файлы отправляются через SMTP (электронная почта). Проект (бесплатный) Apache Commons Codec выполнит эту работу.

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 DatatypeConverter:

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

Ответ 3

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

Используйте http://commons.apache.org/codec/

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

Ответ 4

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

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

--- EDIT:

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