处理InputStream

时间:2010-07-15 13:51:40

标签: java inputstream

如何“修改”InputStream?我有一个文件作为输入,我想修改一些变量并转发一个新的InputStream。

例如,初始InputStream包含Hello $ {var}。然后我想用var =“world”“修改”这个InputStream,产生一个InputStream Hello世界。

这样做的最佳做法是什么?感谢。

3 个答案:

答案 0 :(得分:12)

java.io是一个,所有decorator pattern。利用它并创建一个extends InputStream(可能是DataInputStream或更好,有些Reader的类,因为你真的对字符感兴趣,而不是字节,但是ala),添加一个构造函数获取原始InputStream并覆盖read()方法以读取原始流,将其缓冲到一定程度(例如从${到第一个下一个})然后确定密钥并返回修改后的数据。

如果你打电话给你的新班级FormattedInputStream,那么你可以将new FormattedInputStream(originalInputStream)返回给最终用户,让最终用户仍然只是分配并将其用作InputStream

答案 1 :(得分:4)

您可以尝试继承FilterInputStream

来自文档:

  

FilterInputStream包含一些其他输入流,它用作其基本数据源,可能沿途转换数据或提供其他功能。 FilterInputStream类本身简单地覆盖了InputStream的所有方法,其中的版本将所有请求传递给包含的输入流。 FilterInputStream的子类可以进一步覆盖其中一些方法,还可以提供其他方法和字段。

这是对它的初步尝试。不是解决问题的最佳方法。你可能想要覆盖更多的方法,或许可以选择读者。 (或者甚至可以使用扫描仪并逐行处理文件。)

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

答案 2 :(得分:2)

您可以使用支持文本替换的Streamflyer开箱即用。