InputStream Process

How can I “modify” an InputStream? I have a file as input, I would like to change some variable and forward a new InputStream.

For example, the original InputStream contains Hello $ {var}. Then I want to "change" this InputStream with var = "world", the result is a world of HelloStreamWreamStream.

What is the best practice? Thanks.

+7
java inputstream
source share
3 answers

java.io is one and all decorator pattern . Use it and create a class that extends InputStream (maybe DataInputStream or better, some Reader , since you are really interested in characters, not bytes, but ala), add a constructor that takes the original InputStream and overrides read() methods to read source stream in, buffer it to a certain extent (for example, from ${ until the first time } ), and then determine the key and return the changed data.

If you call your new FormattedInputStream class or so, then you can return new FormattedInputStream(originalInputStream) to enduser instead, and enduser is still just assigned and used as an InputStream .

+12
source share

You can try to subclass FilterInputStream .

From the docs:

A FilterInputStream contains some other input stream that it uses as the main data source, it may convert the data along the way or provide additional functions. The FilterInputStream class itself simply overrides all InputStream methods with versions that pass all requests to the contained input stream. Subclasses of FilterInputStream can optionally override some of these methods and can also provide additional methods and fields.

Here is the initial strike at him. Not the best way to solve this problem. You probably want to override a few more methods and maybe go with the reader. (Or perhaps even use a scanner and process the file line by line.)

 import java.io.*; import java.util.*; public class Test { public static void main(String args[]) throws IOException { String str = "Hello world, this is the value one ${bar} and this " + "is the value two ${foo}"; // The "original" input stream could just as well be a FileInputStream. InputStream someInputStream = new StringBufferInputStream(str); InputStream modified = new SubstitutionStream(someInputStream); int c; while ((c = modified.read()) != -1) System.out.print((char) c); modified.close(); } } class SubstitutionStream extends FilterInputStream { Map<String, String> valuation = new HashMap<String, String>() {{ put("foo", "123"); put("bar", "789"); }}; public SubstitutionStream(InputStream src) { super(src); } LinkedList<Character> buf = new LinkedList<Character>(); public int read() throws IOException { if (!buf.isEmpty()) return buf.remove(); int c = super.read(); if (c != '$') return c; int c2 = super.read(); if (c2 == '{') { StringBuffer varId = new StringBuffer(); while ((c2 = super.read()) != '}') varId.append((char) c2); for (char vc : valuation.get(varId.toString()).toCharArray()) buf.add(vc); return buf.remove(); } else { buf.add((char) c2); return c; } } } 

Output:

 Hello world, this is the value one 789 and this is the value two 123 
+3
source share

You can use Streamflyer , which supports text replacements in character streams out of the box.

+2
source share

All Articles