Поиск строки (как байт []) в двоичном потоке
Привет, команда, я пытаюсь найти строку "Генри" в двоичном файле и изменить строку на другую строку. К вашему сведению, файл является выходом сериализации объекта. Оригинальный вопрос здесь
Я новичок в поиске байтов и думал, что этот код будет искать мой байт [] и обмениваться им. Но он не подходит к работе, он даже не находит соответствия.
{
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 )
Я думаю, что мне нужно двигаться по позициям -4 байта каждый раз, когда я читаю 5 байтов.
Бинго находит это сейчас
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();
}
2 ответа
Следующее может работать для вас, см. Метод 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;
}
}
Самый быстрый способ найти строку в текстовом файле с 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();