Java String.getBytes () проблема - PullRequest
       15

Java String.getBytes () проблема

1 голос
/ 10 января 2012

У меня есть массив байтов.Не имеет значения: я использую библиотеку iText, и при попытке извлечь текст из этого массива каким-то образом происходит сбой.Я проследил, чтобы проблема была связана с поврежденным документом PDF (байтами).Итак, я хотел бы отредактировать массив байтов перед передачей его в библиотеку.

byte[] bytesArray;
String x = new String(bytesArray);
x = x.replace("foo", "bar");
library.parse(x.getBytes());

Чем это отличается от следующего?

library.parse(bytesArray);

Спасибо.

Ответы [ 4 ]

1 голос
/ 10 января 2012

Использование:

  • новая строка (bytesArray, "ISO-8859-1")
  • x.getBytes ( "ISO-8859-1")

Пояснение:

Конструктор new String(byte[]) и метод String.getBytes() используют "кодировку символов по умолчанию для платформы" для преобразования между символами и байтами. Не все последовательности байтов могут быть сопоставлены с символами во всех кодировках символов. Построенная строка будет содержать символ замены юникода \ uFFFD, где были найдены не отображаемые последовательности. Решение состоит в том, чтобы использовать кодировку символов, где каждая последовательность байтов является допустимой. Одним из таких кодировок является ISO-8859-1. (UTF-8, например, не будет работать.)

1 голос
/ 10 января 2012

Это будет проблема кодирования - String, полученный из new String(bytesArray), будет использовать вашу локальную кодировку символов по умолчанию, которая, вероятно, перебивает байты в диапазоне 128 - 255 в другие символы.* Отображение не обязательно 1: 1, поэтому обратное преобразование может вернуть вам массив, отличный от того, с которого вы начали.

0 голосов
/ 10 января 2012

Не добавляется необязательный параметр кодировки символов:

  • new String(bytesArray, "UTF-8")
  • x.getBytes("UTF-8")

Действительно, если кодировка платформыUTF-8 и bytesArray содержат недопустимые последовательности байтов, у вас проблема.


Ниже приведен хороший заменитель байтов.

private void replaceBytes(ByteArrayInputStream in, ByteArrayOutputStream out, String from, String to) {
    try {
        byte[] fromBytes = from.getBytes("Cp1252");
        byte[] toBytes = to.getBytes("Cp1252");
        int fromN = fromBytes.length;
        int fromPos = 0; // Matching input, not written to output.
        for (;;) {
            int b = in.read();
            if (b == -1) {
                if (fromPos != 0) {
                    out.write(fromBytes, 0, fromPos);
                    //fromPos = 0;
                }
                break;
            }
            if (b == fromBytes[fromPos]) {
                ++fromPos;
                if (fromPos >= fromN) {
                    out.write(toBytes);
                    fromPos = 0;
                }
            } else {
                if (fromPos != 0) {
                    out.write(fromBytes, 0, fromPos);
                    fromPos = 0;
                }
                out.write(b);
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
    }
}
0 голосов
/ 10 января 2012

PDF-документ - это двоичный файл. Он не содержит символов и даже меньше символов в кодировке платформы по умолчанию. Предположим, кодировка вашей платформы ASCII. Все байты выше 128 не представляют действительные символы ASCII. Поэтому, когда вы берете массив байтов и делаете его строкой, половина байтов (в среднем) просто не может быть преобразована в символы.

...