Domanda

Ho fatto un semplice packer risorsa per l'imballaggio delle risorse per il mio gioco in un unico file. Tutto stava andando bene fino a quando ho iniziato a scrivere l'unpacker. Ho notato che il file .txt - 26 byte - che avevo preparato, uscito dal file di risorse bene, senza problemi in ogni caso, tutti i dati conservati. Tuttavia, quando la lettura del file .PNG avevo imballato nel file di risorse, i primi 5 byte erano intatti, mentre il resto è stato completamente annullato.

I risalire questo giù per il processo di confezionamento, e ho notato che fread sta leggendo solo i primi 5 byte del file .PNG e non posso per la vita di me capire perché. E anche i trigger 'EOF' per indicare che il file è lungo solo 5 byte, quando in realtà si tratta di un PNG 787 byte di un piccolo poligono, 100px da 100px.

Ho anche testato questo problema facendo un'applicazione separata semplicemente leggere questo file PNG in un buffer, ottengo gli stessi risultati e solo 5-byte vengono letti.

Ecco il codice di quella piccola applicazione separata:

#include <cstdio>

int main(int argc, char** argv)
{
    char buffer[1024] = { 0 };
    FILE* f = fopen("test.png", "r");
    fread(buffer, 1, sizeof(buffer), f);
    fclose(f);        //<- I use a breakpoint here to verify the buffer contents
    return 0;
}

Può qualcuno si prega di precisare il mio stupido errore?

È stato utile?

Soluzione

  

Può qualcuno si prega di precisare il mio stupido errore?

piattaforma Windows, immagino?

Utilizzare questa:

FILE* f = fopen("test.png", "rb");

al posto di questo:

FILE* f = fopen("test.png", "r");

MSDN per la spiegazione.

Altri suggerimenti

L'estensione della risposta corretta da SIGTERM , ecco alcuni retroscena di perché avete ottenuto l'effetto che hai fatto per l'apertura di un file PNG in modalità testo:

Il formato PNG spiega la sua 8 byte file di intestazione come segue:

  

I primi otto byte di un file PNG contiene sempre i seguenti valori:

   (decimal)              137  80  78  71  13  10  26  10
   (hexadecimal)           89  50  4e  47  0d  0a  1a  0a
   (ASCII C notation)    \211   P   N   G  \r  \n \032 \n
  

Questa firma entrambe le identifica il file come file PNG e fornisce per la rilevazione immediata dei problemi di trasferimento file comuni. I primi due byte distinguono file PNG sui sistemi che si aspettano i primi due byte per identificare il tipo di file in modo univoco. Il primo byte è scelto come un valore non ASCII per ridurre la probabilità che un file di testo può essere misconosciuto come file PNG; Inoltre, cattura i trasferimenti di file cattivi chiaro bit 7. Byte due a quattro il nome del formato. La sequenza CR-LF cattura trasferimenti di file non pertinenti che alterano sequenze di nuova riga. Il carattere di controllo-Z si ferma di visualizzazione dei file MS-DOS. Gli ultimi controlli avanzamento riga per l'inverso del problema Traduzione CR-LF.

Credo che in modalità testo, la chiamata a fread() è stata terminata quando ha letto il sesto byte, che contiene un carattere Ctrl + Z. Ctrl + Z è stata storicamente utilizzata in MSDOS (e in CPM prima) per indicare la fine di un file, che era necessario perché il sistema di file memorizzato la dimensione di un file come un conteggio di blocchi, non un conteggio di byte.

Con la lettura del file in modalità testo invece di modalità binaria, si scatta la protezione contro accidentalmente utilizzando il comando TYPE per visualizzare un file PNG.

Una cosa che si potrebbe fare che avrebbe permesso di diagnosticare questo errore è quello di utilizzare fread() in modo leggermente diverso. Non hai testare il valore restituito da fread(). Dovresti. Inoltre, si dovrebbe chiamare in questo modo:

...
size_t nread;
...
nread = fread(buffer, sizeof(buffer), 1, f);

cosicché nread è un conteggio dei byte scritti sul buffer. Per il file PNG in modalità testo, avrebbe detto al primo letto che sola lettura 5 byte. Dal momento che il file non può essere così piccola, si avrebbe avuto un indizio che qualcosa stava succedendo. I restanti byte del buffer non sono mai stati modificati da fread(), che sarebbe stato visto se inizializzato il buffer per qualche altro valore di riempimento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top