legge il file bytewise e trova le informazioni

0

Sono un php-dev per hobby e ho il seguente problema:

Ho un file rar, la cui intestazione è danneggiata, quindi l'estrazione non è completamente possibile. il contenuto non è compresso e può essere letto con es. un editor esadecimale. l'archivio contiene file jpeg, ma a causa dell'intestazione danneggiata, alcuni di essi non sono estraibili in winrar. Ho provato a riparare, ma una buona parte del file rimane rotta.

Voglio leggere il file e cercare i byte che indicano l'inizio e la fine di un file jpeg (da quello che so sono FFD8FF per l'avvio e FFD9FF per il fine). usando un editor esadecimale sono riuscito a trovare alcuni di quei byte, e anche l'estrazione dell'immagine in un file e la visualizzazione funziona. dal momento che il file è 500mb, voglio farlo automaticamente, e dal momento che sono php-friendly, mi piacerebbe farlo lì: -)

so come leggere un file bytewise (fread), quello che sto avendo difficoltà è, analizzare il file correttamente in esadecimale, così posso identificare gli inizi e le fini. quello a cui sto pensando è qualcosa del genere (in pseudocodice):

while( READ FILE UNTIL EOF ){
    if( CURRENTBYTES == FFD8FF ){
        $jpeg_file = READ FILE UNTIL CURRENTBYTES == FFD9FF
        fwrite($jpeg_file, "xyz.jpg");
        // return to while, looking for next FFD8FF
    }
}

qualcuno potrebbe darmi un suggerimento, come la lettura e l'identificazione sarebbero fatte meglio? la domanda principale è, come posso leggere un file fino a un byte iniziale, quindi salvare quanto segue, quindi cercare il prossimo byte iniziale? efficienza, sicurezza, codice bellezza non sono un problema, voglio solo tutte le foto: -)

molti ringraziamenti per qualsiasi aiuto

    
posta benny.utzer 11.09.2015 - 15:12
fonte

2 risposte

1

Poiché l'efficienza non è un problema e 500mb non è più così grande, l'opzione più semplice sarebbe:

  • legge il file nella stringa $blob (suggerimento: file_get_contents ).
  • ottiene ogni parte separata in un array $parts . Soluzione brutta: preg_match_all('/\xff\xd8\xff(.*?)\xff\xd9\xff/', $blob, $matches) , quindi ispeziona la forma dell'elenco $matches in seguito.
  • salva ogni $ parte in un file separato, ad esempio usando il md5sum del file come filename. (MD5sum dovrebbe essere abbastanza buono per questo)

Questo dovrebbe essere abbastanza suppongo.

    
risposta data 11.09.2015 - 21:35
fonte
1

Vorrei passare attraverso il file, invece di leggerlo tutto in una volta. Cerca il primo byte (0xFF) e, quando viene trovato, verifica se il byte successivo è 0xD8. In tal caso, apri il file di output e scrivi quei due byte, seguito da ciascun byte fino a raggiungere il modello finale. Cercalo allo stesso modo dei byte iniziali e chiudi l'output del file quando viene rilevato.

L'utilizzo della memoria sarà molto inferiore. Se dovrebbe essere eseguito molto più velocemente rispetto all'utilizzo di un'espressione regolare.

Questa è fondamentalmente una macchina a stati molto semplice.

    
risposta data 14.09.2015 - 07:13
fonte

Leggi altre domande sui tag