如何使用 FilterInputStream 就地替换两个或多个占位符?

How to replace two or more placeholders in-place using FilterInputStream?

提问人:John Doe 提问时间:3/9/2021 更新时间:3/9/2021 访问量:339

问:

我有一些带有占位符的XML文件,我需要找到这些占位符并将其替换为值。但是,我不想创建临时文件。我需要的是这样描述的:

筛选(搜索和替换)InputStream 中的字节数组

简而言之,我想使用 FilterInputStream 并动态替换占位符。

在您的许可下,为了更清楚起见,我将把代码放在这里:

import java.io.*;
import java.util.*;

class ReplacingInputStream extends FilterInputStream {

    LinkedList<Integer> inQueue = new LinkedList<Integer>();
    LinkedList<Integer> outQueue = new LinkedList<Integer>();
    final byte[] search, replacement;

    protected ReplacingInputStream(InputStream in,
                                   byte[] search,
                                   byte[] replacement) {
        super(in);
        this.search = search;
        this.replacement = replacement;
    }

    private boolean isMatchFound() {
        Iterator<Integer> inIter = inQueue.iterator();
        for (int i = 0; i < search.length; i++)
            if (!inIter.hasNext() || search[i] != inIter.next())
                return false;
        return true;
    }

    private void readAhead() throws IOException {
        // Work up some look-ahead.
        while (inQueue.size() < search.length) {
            int next = super.read();
            inQueue.offer(next);
            if (next == -1)
                break;
        }
    }

    @Override
    public int read() throws IOException {    
        // Next byte already determined.
        if (outQueue.isEmpty()) {
            readAhead();

            if (isMatchFound()) {
                for (int i = 0; i < search.length; i++)
                    inQueue.remove();

                for (byte b : replacement)
                    outQueue.offer((int) b);
            } else
                outQueue.add(inQueue.remove());
        }

        return outQueue.remove();
    }

    // TODO: Override the other read methods.
}

这对于一个占位符非常有效,但如果我需要替换两个占位符怎么办?就我而言,占位符具有不同的长度。例如:

byte[] firstPlaceholder = "abc".getBytes("UTF-8");
byte[] secondPlaceholder = "replace_this".getBytes("UTF-8");

以及包含占位符的字符串:

"Hello abc world, I want to replace_this line here"
java 文件-io io 输入流 nio

评论

1赞 3/9/2021
简单的解决方案:是一个可以链接的,即),search2,repl2)'(可能不适合很多替换) - 否则编码会太复杂而无法注释FilterInputStreamInputStreamnew ReplacingInputStream(new ReplacingInputStream(inputStream, search1, repl
0赞 John Doe 3/9/2021
嗯。。好主意,谢谢。
0赞 John Doe 3/9/2021
@user15244370 - 看起来这就是我需要的。我检查了一下,效果很好。如果你写一个答案,我会接受的。

答: 暂无答案