【问题标题】:Process InputStream处理输入流
【发布时间】:2010-07-15 13:51:40
【问题描述】:

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

例如,初始 InputStream 包含 Hello ${var}。然后我想用 var = "world" 来“修改”这个 InputStream,得到一个 InputStream Hello world。

执行此操作的最佳做​​法是什么?谢谢。

【问题讨论】:

    标签: java inputstream


    【解决方案1】:

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

    如果您将新类称为FormattedInputStream 左右,那么您可以将new FormattedInputStream(originalInputStream) 返回给最终用户,而最终用户仍然只是将其分配并用作InputStream。

    【讨论】:

    【解决方案2】:

    您可以尝试子类化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) 更容易。
    • 啊哈,我没有意识到 DataInputStream 是一个 FilterInputStream。 (虽然有道理。)那么 DataInputStream 提供了什么 FilterInputStream 没有(在这种情况下很有用。)
    【解决方案3】:

    您可以使用Streamflyer,它支持开箱即用的字符流中的文本替换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 2016-01-16
      • 1970-01-01
      • 2018-06-13
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      相关资源
      最近更新 更多