【问题标题】:Efficient way match a regex Pattern on an OutputStream greater than max String limit有效方式匹配大于最大字符串限制的输出流上的正则表达式模式
【发布时间】:2020-02-29 12:38:29
【问题描述】:

我正在尝试找到一种有效的方法来对大小超过 String's max size 的 ByteArrayOutputStream 进行模式匹配。

对适合单个字符串的 ByteArrayOutputStream 进行模式匹配很简单:

private boolean doesStreamContainPattern(Pattern pattern, ByteArrayOutputStream baos) throws IOException {

    /*
     *  Append external source String to output stream...
     */

    if (pattern != null) {
        String out = new String(baos.toByteArray(), "UTF-8");
        if (pattern.matcher(out).matches()) {
            return true;
        }
    }

    /*
     *  Some other processing if no pattern match
     */
    return false;
}

但是如果baos的大小超过了String max size,问题就变成了:

  1. baos 输入到多个字符串中。
  2. “滑动”模式匹配这些多个字符串的串联(即原始 baos 内容)。

第 2 步看起来比第 1 步更具挑战性,但我知道像 Unix sed 这样的实用程序只能在文件上执行此操作。

实现这一目标的正确方法是什么?

【问题讨论】:

  • 我认为匹配OutputStream 没有多大意义,不是吗?您不是在写入流,而是在读取它 - 所以它应该是 InputStream

标签: java string outputstream


【解决方案1】:

您可以编写一个简单的包装类来从流中实现CharSequence

class ByteArrayCharSequence implement CharSequence {
    private byte[] array;
    public StreamCharSequence(byte[] input) {
        array = input;
    }

    public char charAt(int index) {
        return (char) array[index];
    }
    public int length() {
        return array.length;
    }
    public CharSequence subSequence(int start, int end) {
        return new ByteArrayCharSequence(Arrays.copyOfRange(array, start, end));
    }
    public String toString() {
        // maybe test whether we exceeded max String length
    }
}

然后匹配

private boolean doesStreamContainPattern(Pattern pattern, ByteArrayOutputStream baos) throws IOException {
    if (pattern != null) {
        CharSequence seq = new ByteArrayCharSequence(baos.toByteArray());
        if (pattern.matcher(seq).matches()) {
            return true;
        }
    }

    /*
     *  Some other processing if no pattern match
     */
    return false;
}

投射到char 和使用copyOfRange 的边缘显然很粗糙,但它应该适用于大多数情况,您可以针对不适用的情况进行调整。

【讨论】:

  • 感谢您和 +1 的帮助。请注意,您的解决方案还受到 CharSequence (Integer.MAX_VALUE) 的固有大小/长度限制的限制。我现在认为解决方案应该更倾向于使用ScannerFileOutputStream
  • 好吧,Integer.MAX_VALUE 最多可以处理 2 GB 的数据,但我想无论哪种方式,Scanner 都是个好主意。您会发现它接受InputStream 而不是OutputStream,正如我在之前对该问题的评论中指出的那样更有意义。
猜你喜欢
  • 2021-07-31
  • 1970-01-01
  • 2019-03-16
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 2015-11-14
  • 1970-01-01
相关资源
最近更新 更多