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
aioobe
source share