【问题标题】:Find a string inside a bytebuffer在字节缓冲区中查找字符串
【发布时间】:2023-03-16 17:28:01
【问题描述】:

我正在从 C 切换到 Java。我想知道如何在字节缓冲区中找到一个字符串,java中是否有类似 memchr 的东西?字节缓冲区只是部分字符串,其余部分是原始字节,因此任何 java 方法都必须处理字节 + 字符。

我也在 java 中寻找类似 strsep 的东西来分割字符串。

【问题讨论】:

  • java.lang.String - 方法 split() 或 substring 可用于拆分字符串。一般来说,您应该阅读此类的 javadocs。
  • 你可以用String.split()分割字符串
  • @Blub - 字节缓冲区的大小/长度是多少?
  • 不是一个好问题 - 因为它有两个问题。请把两者分开(使用拆分?:-))

标签: java string bytebuffer


【解决方案1】:

您可以将 ByteBuffer 转换为 String 并使用 indexOf 可能会起作用。

ByteBuffer bb = /* non-direct byte buffer */
String text = new String(bb.array(), 0, bb.position(), bb.remaing());
int index = text.indexOf(searchText);

这有一个重要的开销,因为它创建了一个字符串。另一种方法是蛮力字符串搜索,它会更快但需要时间编写。

【讨论】:

  • 不推荐使用此 String 构造函数,因为它不考虑字符编码。建议:String text = new String(bb.array(), 0, bb.position(), charset); 其中charset 是要使用的编码,或默认的Charset.defaultCharset()
  • 如果您正在读取原始 C 字符串,它很可能是 ISO-8859-1 编码的,在这种情况下这种方法很好。明确不会对性能造成太大影响,因此明确可能会更好。
  • 这种方法和类似方法的缺点是您必须阅读整个字符串 - 而不是流式解决方案。
【解决方案2】:

您需要使用适用于您的应用程序的正确字符编码将字符串编码为字节。然后使用 Rabin-Karp 或 Boyer-Moore 之类的字符串搜索算法在缓冲区中查找结果字节序列。或者,如果您的缓冲区很小,您可以执行蛮力搜索。

我不知道这些搜索算法的任何开源实现,它们不是核心 Java 的一部分。

【讨论】:

    【解决方案3】:

    来自Fastest way to find a string in a text file with java

    我在 MIMEParser 中找到的最佳实现:https://github.com/samskivert/ikvm-openjdk/blob/master/build/linux-amd64/impsrc/com/sun/xml/internal/org/jvnet/mimepull/MIMEParser.java

    /**
      * Finds the boundary in the given buffer using Boyer-Moore algo.
      * Copied from java.util.regex.Pattern.java
      *
      * @param mybuf boundary to be searched in this mybuf
      * @param off start index in mybuf
      * @param len number of bytes in mybuf
      *
      * @return -1 if there is no match or index where the match starts
      */
    
      private int match(byte[] mybuf, int off, int len) {
    

    还需要:

      private void compileBoundaryPattern();
    

    【讨论】:

      【解决方案4】:

      String 类有一个不错的拆分方法String.split

      【讨论】:

        【解决方案5】:

        一种选择是使用StringTokenizer,它可以根据给定的分隔符将字符串拆分为可迭代的标记集合。如果需要,令牌集合可以包含分隔符。示例:

        String s = "abc:def-ghi|jkl";
        StringTokenizer tokenizer = new StringTokenizer(s, ":-|");
        while (tokenizer.hasMoreTokens()) {
          System.out.print(tokenizer.nextToken());
        }
        

        预期结果:

        abcdefghijkl

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-11-24
          • 1970-01-01
          • 2012-07-17
          • 2010-10-13
          • 1970-01-01
          • 2013-07-10
          相关资源
          最近更新 更多