开发者

Substitute chars on Java 1.4 InputStream

I have an InputStream that is returning, for example:

<?xml version='1.0' ?><env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><bbs:rule xmlns:bbs="http://com.foo/bbs">

I then pass the stream to a method that return a byte array. I'd like to substitute "com.foo" with something else, like "org.bar" before I pass to the byte[] method.

What is a good way to do 开发者_运维问答that?


If you have a bytearray you can transform it into a String. Pay attention to the encoding, in the example I use utf-8. I think this is a simple way to do that:

String newString = new String(byteArray, "utf-8");
newString = newString.replace("com.foo", "org.bar");
return newString.getBytes("utf-8");


One way is to wrap your InputStream in your own FilterInputStream subclass that does the transformation on the fly. It will have to be a look-ahead stream that checks every "c" character to see if it is followed by "om.foo" and if so make the substitution. You'll probably have to override just the read() method.


A stream reads/writes bytes. Trying to replace text in a binary representation is asking for trouble. So the first thing to do would be wrapping this stream into a Reader (like InputStreamReader) which will take care of translating the binary data into character information for you. You'll have to know the encoding of your streamed data, however, to make sure it is interpreted correctly. For example, UTF-8 or ISO-8859-1.

Once you have your textual data, you can think of how to replace parts of it. One way to do this is using regular expressions. However, this means you'll first have to read the entire stream into a string, do the substitution and then return the byte array. For large amounts of data, this might be inefficient.

Since you're dealing with XML data, you could make use of a higher-level approach and parse the XML in some way that allows you to process the contents without having to store them entirely in an intermediate format. A SAXParser with your own ContentHandler would do the trick. As events arrive, simply write them out again but with the proper alterations. Another approach would be an XSLT transformation with some extension function magic.

Wasn't there supposed to be some support for stream manipulations like this in java.nio? Or was this planned for an upcoming Java version?


This may not be the most efficient way to do it, but it certainly works.

    InputStream is = // input;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(baos));

    String line = null;

    while((line = reader.readLine()) != null)
    {
        if(line.contains("com.foo"))
        {
            line = line.replace("com.foo", "org.bar");
        }

        writer.write(line);
    }

    return baos.toByteArray();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜