PHP kullanarak bir ikili dosyada belirli bir Bayt dizisini bulmak istiyorum. Çok fazla 0s ve 1s yazmayı önlemek için bu diziyi onaltılık olarak temsil ettim. Bulunacak sekans 0x4749524f
.PHP'de bir ikili dosyada bir bayt dizisi mi arıyorsunuz?
$mysequence = "4749524f";
$f = fopen($filename, "r") or die("Unable to open file!");
while(!feof($f)){
$seq = fread($f, 4);
if(bin2hex($seq) == $mysequence){
echo "found!";
break;
}
else if(!feof($f)) fseek($f, -3, SEEK_CUR);
}
Ne algoritması yapar basittir: Bu şimdi için geldi çalışma çözümdür
- Oku 4 Bayt
- Kontrol eğer olurlarsa ise dizinin
- eşittir onlar eşittir -> bulundu! Yürütmeyi durdur.
- tutuyorsa değildir ve ben dosyanın sonuna değilim Eğer Neden 3 Bayt geri gitmek adım 1.
geri 3 Bayt dosyasına gidip tekrar? Bu dosyanın içeriği ise Çünkü:
0000 4749 524f 0000 01b0 0013
geri 3 Bytes gitmezseniz, ben üçüncü saniye birinci tekrar 0000 4749
, 524f 0000
, 01b0 0013
okuyacak gibi görebileceğiniz diziyi özledim.
Sorun: Cehennem gibi yavaş ... Uygulama, 50 MB büyüklüğe kadar dosyalar ile çalışmak zorunda kalacak, bu yüzden bu diziyi bulmak sonsuza dek sürecek.
PHP'de işi yapacak optimize edilmiş bir işlev var mı? Bunu yapmak için daha hızlı (benimki gibi değil) bir yolu var mı?
1M (veya daha fazla) gibi uzun bir bayt kümesi okuyun. Sonra bunu hafızada arayın. Sonraki 1Mbyte'ları okurken, ilk setin son 3'ünün iğnenin başlangıcı olup olmadığını da kontrol edin. –
Tamam, deneyeceğim! Teşekkürler. BTW, dosya okunurken belleğe önbelleklendiğini düşündüm ... Bu işlevi çalıştırdığım her zaman, dosya sabit diskten doğrudan okunabilir mi? –
@AlbertoFontana Sadece aynı yaklaşımın bir modifikasyonu, sadece büyük parçalarda (4-8k iddia ediyorum) ve sonra bir "yığın içinde bul" (vs "chunk exact match") olarak okunur). Bölünmüş parçaları kolayca işlemek için basit bir yol da geri aramaktır, bu nedenle parçalar aslında birkaç bayt ile örtüşür (bu yakın çekim nispeten seyrek yapılırsa çok iyi olur). Sistem çağrı sayısının azaltılması, en büyük performans farkı ne olacak. Ayrıca, her zaman okunan verileri dönüştürmek yerine, $ mysequence'ı bayt dizisine dönüştürerek biraz daha fazla iş azaltılabilir. – user2864740