高效的ByteArrayInputStream操作

时间:2012-03-15 19:32:07

标签: java bytearray bytearrayinputstream

我正在使用ByteArrayInputStream,其中包含一个XML文档,该文档由一个元素组成,该元素具有一个大的base 64编码字符串作为元素的内容。我需要删除周围的标签,以便我可以解码文本并将其输出为pdf文档。

最有效的方法是什么?

我的下意识反应是将流读入byte数组,找到开始标记的结尾,找到结束标记的开头,然后将中间部分复制到另一个byte阵列;但这似乎效率很低,我正在处理的文本有时会很大(128KB)。我想要一种方法来做到这一点,而无需额外的byte数组。

2 个答案:

答案 0 :(得分:2)

Base 64不使用字符<>,因此我假设您使用的是web安全的base64变体,这意味着您无需担心内容中的HTML实体或注释。 如果您确定内容具有此表单,请执行以下操作:

  1. 从右侧扫描,寻找'<'。这将是关闭标记的开头。
  2. 从该位置向左扫描,寻找'>'。这将是开始标记的结尾。
  3. 基础64内容介于这两个位置之间,不受限制。

    您可以使用

    来预设第二个阵列
    ((end - start + 3) / 4) * 3
    

    作为解码内容长度的上限,然后b64解码到其中。这是有效的,因为每4个base64数字编码3个字节。

    如果你想得到真正的花哨,因为你知道数组的前几个字节包含可忽略的标签数据,并且编码数据小于输入,你可以通过当前的字节缓冲区破坏性地解码数据。

答案 1 :(得分:0)

在阅读信息流时进行搜索和转换。

// 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 上面是我的网页浏览器,因此可能存在语法错误。