【发布时间】:2010-07-15 13:51:40
【问题描述】:
如何“修改”一个 InputStream?我有一个文件作为输入,我想修改一些变量并转发一个新的 InputStream。
例如,初始 InputStream 包含 Hello ${var}。然后我想用 var = "world" 来“修改”这个 InputStream,得到一个 InputStream Hello world。
执行此操作的最佳做法是什么?谢谢。
【问题讨论】:
标签: java inputstream
如何“修改”一个 InputStream?我有一个文件作为输入,我想修改一些变量并转发一个新的 InputStream。
例如,初始 InputStream 包含 Hello ${var}。然后我想用 var = "world" 来“修改”这个 InputStream,得到一个 InputStream Hello world。
执行此操作的最佳做法是什么?谢谢。
【问题讨论】:
标签: java inputstream
java.io 是一个和所有decorator pattern。利用它并创建一个extends InputStream 的类(可能是DataInputStream 或更好,一些Reader 因为您实际上对字符感兴趣,而不是字节,而是ala),添加一个采用原始@987654329 的构造函数@ 并覆盖 read() 方法来读取原始流,将其缓冲到一定程度(例如,从 ${ 直到 with firstnext }),然后确定密钥并返回修改后的数据。
如果您将新类称为FormattedInputStream 左右,那么您可以将new FormattedInputStream(originalInputStream) 返回给最终用户,而最终用户仍然只是将其分配并用作InputStream。
【讨论】:
您可以尝试子类化FilterInputStream。
来自文档:
FilterInputStream 包含一些其他输入流,将其用作其基本数据源,可能在此过程中转换数据或提供附加功能。类 FilterInputStream 本身只是简单地覆盖 InputStream 的所有方法,其版本将所有请求传递给包含的输入流。 FilterInputStream 的子类可能会进一步覆盖其中一些方法,也可能提供额外的方法和字段。
这是一个初步的尝试。不是解决它的最佳方法。您可能想要覆盖更多的方法,或者使用阅读器来代替。 (或者甚至可能使用 Scanner 并逐行处理文件。)
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;
}
}
}
输出:
Hello world, this is the value one 789 and this is the value two 123
【讨论】:
DataInputStream :) 的原因(它是它的子类)。不过,毕竟在内部使用Reader (InputStreamReader) 更容易。
您可以使用Streamflyer,它支持开箱即用的字符流中的文本替换。
【讨论】: