【问题标题】:Search for a String (as an byte[]) in a binary stream在二进制流中搜索字符串(作为字节 [])
【发布时间】:2014-03-06 19:23:43
【问题描述】:

您好团队,我正在尝试在二进制文件中查找字符串“Henry”并将该字符串更改为不同的字符串。仅供参考,该文件是对象序列化的输出。 Original Question here

我是搜索字节的新手,并想象这段代码会搜索我的 byte[] 并交换它。但它并没有接近工作它甚至找不到匹配项。

{
    byte[] bytesHenry = new String("Henry").getBytes();
    byte[] bytesSwap = new String("Zsswd").getBytes();

    byte[] seekHenry = new byte[bytesHenry.length];

    RandomAccessFile file = new RandomAccessFile(fileString,"rw");

    long filePointer;
    while (seekHenry != null) {
       filePointer = file.getFilePointer();
       file.readFully(seekHenry);
       if (bytesHenry == seekHenry) {
           file.seek(filePointer);
           file.write(bytesSwap);
           break;
       }
     }
}

好的,我看到了bytesHenry==seekHenry 的问题,我会换成Arrays.equals( bytesHenry , seekHenry )

我认为每次读取 5 个字节时我需要移动 -4 个字节位置。


它现在找到了宾果游戏

    while (seekHenry != null) {
                    filePointer = file.getFilePointer();
                    file.readFully(seekHenry);;
                    if (Arrays.equals(bytesHenry,
                                      seekHenry)) {
                        file.seek(filePointer);
                        file.write(bytesSwap);
                        break;
                    }
                    file.seek(filePointer);
                    file.read();
                }

【问题讨论】:

  • 如果您发现我的原始答案对打开这个问题很有用,至少要支持我的原始答案:)
  • 我正在测试写入是否正常工作。 ;)
  • 您是否使用最大字符串长度进行搜索?
  • 如果是,您可以读取并缓存在环形缓存缓冲区中
  • 对于这个例子,它是一个“亨利”,但我有兴趣听到未来更好的方法。

标签: java serialization seek randomaccessfile


【解决方案1】:

以下内容可能对您有用,请参阅方法 search(byte[] input, byte[] searchedFor),它返回第一个匹配项匹配的索引或 -1。

public class SearchBuffer {

    public static void main(String[] args) throws UnsupportedEncodingException {
        String charset= "US-ASCII";
        byte[] searchedFor = "ciao".getBytes(charset);
        byte[] input = "aaaciaaaciaojjcia".getBytes(charset);

        int idx = search(input, searchedFor);
        System.out.println("index: "+idx); //should be 8
    }

    public static int search(byte[] input, byte[] searchedFor) {
        //convert byte[] to Byte[]
        Byte[] searchedForB = new Byte[searchedFor.length];
        for(int x = 0; x<searchedFor.length; x++){
            searchedForB[x] = searchedFor[x];
        }

        int idx = -1;

        //search:
        Deque<Byte> q = new ArrayDeque<Byte>(input.length);
        for(int i=0; i<input.length; i++){
            if(q.size() == searchedForB.length){
                //here I can check
                Byte[] cur = q.toArray(new Byte[]{});
                if(Arrays.equals(cur, searchedForB)){
                    //found!
                    idx = i - searchedForB.length;
                    break;
                } else {
                    //not found
                    q.pop();
                    q.addLast(input[i]);
                }
            } else {
                q.addLast(input[i]);
            }
        }

        return idx;
    }
}

【讨论】:

    【解决方案2】:

    来自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();
    

    【讨论】:

      猜你喜欢
      • 2020-09-27
      • 2021-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2020-05-06
      相关资源
      最近更新 更多