[英]Remove junk trailing xml from an inputstream
我的免费网络主机将分析javascript附加到所有PHP和HTML文件。 很好,除了我想将XML发送到我的Android应用程序之外,这会使我的文件无效。
由于XML在传递给我的SAX ContentHandler之前已进行了完整的分析(并且分解),所以我不能只是捕捉到异常并与充实的对象一起愉快地继续工作。 (我尝试过,然后对此感到毛骨悚然。)
对合理有效的策略有何建议?
我将要创建一个类,该类将接收我的InputStream,仔细阅读直到找到垃圾,然后中断,然后接受我刚刚写的内容,将其转换回InputStream并传递它,就像什么都没有发生。 但是我担心它的效率会非常低下,有一些我不需要处理的错误(例如破坏诸如嵌入式图像之类的二进制值)并且希望是不必要的。
FWIW,这是一个Android项目的一部分,因此我正在使用android.util.Xml
类(请参阅源代码 )。 当我跟踪异常时,它带我去了一个本地的 appendChars函数,无论如何它本身都是从私有方法网络中调用的,因此对任何子类进行子类化似乎都是无用的。
这是我的堆栈跟踪中的重要内容:
E/AndroidRuntime( 678): Caused by: org.apache.harmony.xml.ExpatParser$ParseException: At line 3, column 0: junk after document element
E/AndroidRuntime( 678): at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:523)
E/AndroidRuntime( 678): at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:482)
E/AndroidRuntime( 678): at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:320)
E/AndroidRuntime( 678): at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:277)
我想最后我要征询有关InputStream->手动解析为OutputStream->重新创建InputStream->传递解决方案的意见是否像我认为的那样可怕。
免费的虚拟主机有此问题。 我仍然没有找到一种仍然处于免费模式的替代方案。
“我将创建一个类,将使用我的InputStream,仔细阅读它,直到找到垃圾,然后断开,然后接受我刚刚写的内容,将其转换回InputStream,并像没有发生任何事情一样传递给我。 “我担心它的效率会非常低下,有一些我不需要处理的错误(例如破坏诸如嵌入式图像之类的二进制值)并且希望是不必要的。”
可以的 您可以读入StringBuffer,然后使用ByteArrayInputStream或类似的东西(如适用的话,如StreamReader)。
http://developer.android.com/reference/java/io/ByteArrayInputStream.html
不利的一面是您将整个XML文件读入内存,对于大文件,这在内存方面可能是低效的。
另外,您可以继承InputStream的子类并通过流进行过滤。 您可能只需要通过调用super.read()来覆盖3个read()方法,并在到达垃圾端时进行标记,然后根据需要返回EOF。
我将要创建一个类,该类将接收我的InputStream,仔细阅读直到找到垃圾,然后中断,然后接受我刚刚写的内容,将其转换回InputStream并传递它,就像什么都没有发生。 但是我担心它的效率会非常低下,有一些我不需要处理的错误(例如破坏诸如嵌入式图像之类的二进制值)并且希望是不必要的。
您可以使用FilterStream而不需要缓冲区
最好的做法是在XML的末尾添加一个定界符,例如
--theXML ends HERE --
或在XML中找不到的字符,例如一组16个\\u04\u003c/code>字符
(然后您只需要检查第16个字节)就可以了。 XML的末尾并阅读直到找到它为止
假设
\\u04\u003c/code> delim的实现
class WebStream extends FilterInputStream {
byte[] buff = new byte[1024];
int offset = 0, length = 0;
public WebStream(InputStream i) {
super(i);
}
@Override
public boolean markSupported() {
return false;
}
@Override
public int read() throws IOException {
if (offset == length)
readNextChunk();
if (length == -1)
return -1;// eof
return buff[offset++];
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
if (offset == length)
readNextChunk();
if (length == -1)
return -1;// eof
int cop = length - offset;
if (len < cop)
cop = len;
System.arraycopy(buff, offset, b, off, cop);
offset += cop;
return cop;
}
private void readNextChunk() throws IOException {
if (offset <= length) {
System.arraycopy(buff, offset, buff, 0, length - offset);
length -= offset;
offset = 0;
}
int read = in.read(buff, length, buff.length - length);
if (read < 0 && length <= 0) {
length = -1;
offset = 0;
return;
}
// note that this is assuming ascii compatible
// anything like utf16 or utf32 will break here
for (int i = length; i < read + length; i += 16) {
if (buff[i] == 0x04) {
while (buff[--i] == 0x04)
;// find beginning of delim block
length = i;
read = 0;
}
}
}
}
请注意,这会抛出错误,进行一些错误检查并需要适当的调试
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.