Эффективное манипулирование ByteArrayInputStream - PullRequest
2 голосов
/ 15 марта 2012

Я работаю с ByteArrayInputStream, который содержит XML-документ, состоящий из одного элемента с большой строкой в ​​кодировке 64 в качестве содержимого элемента. Мне нужно удалить окружающие теги, чтобы я мог декодировать текст и выводить его в виде документа PDF.

Какой самый эффективный способ сделать это?

Моя реакция коленного рывка - прочитать поток в массив byte, найти конец начального тега, найти начало конечного тега и затем скопировать среднюю часть в другой массив byte; но это кажется довольно неэффективным, и текст, с которым я работаю, иногда может быть большим (128 КБ). Я хотел бы сделать это без лишних byte массивов.

Ответы [ 2 ]

2 голосов
/ 15 марта 2012

Base 64 не использует символы < или >, поэтому я предполагаю, что вы используете веб-безопасный вариант base64, означающий, что вам не нужно беспокоиться о сущностях HTML или комментариях внутри содержимого. Если вы действительно уверены, что содержание имеет эту форму, выполните следующие действия:

  1. Сканирование справа ищет '<'. Это будет начало закрывающего тега.
  2. Сканирование влево от этой позиции в поисках '>'. Это будет конец начального тега.

Содержимое базы 64 находится между этими двумя позициями, исключая.

Вы можете настроить ваш второй массив, используя

((end - start + 3) / 4) * 3

в качестве верхней границы длины декодированного содержимого, а затем кодировать в нее b64. Это работает, потому что каждые 4 цифры base64 кодируют 3 байта.

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

0 голосов
/ 16 марта 2012

Выполняйте поиск и преобразование во время чтения потока.

// find the start tag
byte[] startTag = new byte[]{'<', 't', 'a', 'g', '>'};
int fnd = 0;
int tmp = 0;
while((tmp = stream.read()) != -1) {
 if(tmp == startTag[fnd]) 
  fnd++;
 else
  fnd=0;
 if(fnd == startTage.size()) break;
}

// get base64 bytes
while(true) {
 int a = stream.read();
 int b = stream.read();
 int c = stream.read();
 int d = stream.read();
 byte o1,o2,o3; // output bytes
 if(a == -1 || a == '<') break;
 //
 ...
 outputStream.write(o1);
 outputStream.write(o2);
 outputStream.write(o3);
}

note Выше написано в моем веб-браузере, поэтому могут существовать синтаксические ошибки.

...