it-swarm.com.de

Eine binäre Datei wird 1 Byte auf einmal gelesen

Ich versuche, eine binäre Datei in C 1 Byte auf einmal zu lesen, und nachdem ich stundenlang im Internet gesucht habe, kann ich immer noch nichts anderes als Müll und/oder einen Seg-Fehler abrufen. Grundsätzlich ist die Binärdatei im Format einer Liste, die 256 Elemente lang ist, und jedes Element ist 1 Byte (ein vorzeichenloser Integerwert zwischen 0 und 255). Ich versuche, Fseek und Fread zu verwenden, um zum "Index" in der Binärdatei zu springen und diesen Wert abzurufen. Der Code, den ich derzeit habe:

unsigned int buffer;

int index = 3; // any index value

size_t indexOffset = 256 * index;
fseek(file, indexOffset, SEEK_SET);
fread(&buffer, 256, 1, file);

printf("%d\n", buffer);

Im Moment gibt mir dieser Code zufällige Müllnummern und seg Fehler. Irgendwelche Tipps, wie ich das richtig zum Laufen bringen kann?

18
RogerB

In Ihrem Code versuchen Sie, 256 Byte an die Adresse eines Int zu lesen. Wenn Sie jeweils ein Byte lesen möchten, rufen Sie fread(&buffer, 1, 1, file); (Siehe fread ) auf.

Eine einfachere Lösung besteht jedoch darin, ein Byte-Array zu deklarieren, alles zusammen zu lesen und anschließend zu verarbeiten.

16
MByD

Ihre verwirrenden Bytes mit int . Der gebräuchliche Begriff für ein Byte ist ein unsigniertes Zeichen . Die meisten Bytes sind 8 Bit breit. Wenn die Daten, die Sie lesen, 8 Bit sind, müssen Sie 8 Bit einlesen:

#define BUFFER_SIZE 256

unsigned char buffer[BUFFER_SIZE];

/* Read in 256 8-bit numbers into the buffer */
size_t bytes_read = 0;
bytes_read = fread(buffer, sizeof(unsigned char), BUFFER_SIZE, file_ptr);
// Note: sizeof(unsigned char) is for emphasis

Der Grund für das Lesen aller Daten in den Speicher besteht darin, die E/A fließend zu halten. Jede Eingabeaufforderung ist unabhängig von der angeforderten Menge mit einem Overhead verbunden. Das Lesen eines Bytes zu einer Zeit oder das Suchen einer Position zu einer Zeit ist der ungünstigste Fall. 

Hier ist ein Beispiel für den zum Lesen von 1 Byte erforderlichen Overhead:

Tell OS to read from the file.
OS searches to find the file location.
OS tells disk drive to power up.
OS waits for disk drive to get up to speed.
OS tells disk drive to position to the correct track and sector.
-->OS tells disk to read one byte and put into drive buffer.
OS fetches data from drive buffer.
Disk spins down to a stop.
OS returns 1 byte to your program.

In Ihrem Programmdesign werden die obigen Schritte 256 Mal wiederholt. Mit jedem Vorschlag wird die mit "->" markierte Zeile 256 Byte lesen. Daher wird der Overhead nur einmal statt 256-mal ausgeführt, um dieselbe Datenmenge zu erhalten.

14
Thomas Matthews
unsigned char buffer; // note: 1 byte
fread(&buffer, 1, 1, file);

Es ist Zeit, mans zu lesen, glaube ich. 

3
c-smile

Sie versuchen, 256 Byte in eine 4-Byte-Integer-Variable mit dem Namen "Puffer" zu lesen. Sie überschreiben die nächsten 252 Bytes anderer Daten.

Anscheinend sollte buffer entweder unsigned char buffer[256]; sein oder Sie sollten fread(&buffer, 1, 1, f) ausführen, und in diesem Fall sollte bufferunsigned char buffer; sein. 

Wenn Sie nur ein einzelnes Zeichen wünschen, können Sie alternativ buffer als int belassen ( unsigned ist nicht erforderlich, da C99 einen ausreichenden Mindestbereich für plain int garantiert) und sagen Sie einfach:

buffer = fgetc(f);
1
DigitalRoss

Ein paar Probleme mit dem Code, wie er steht.

Der Prototyp für Fread ist:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

Sie haben die Größe auf 256 (Bytes) und die Zählung auf 1 festgelegt. Das ist in Ordnung, das heißt "einen Satz von 256 Bytes lesen, in den Puffer schieben".

Ihr Puffer ist jedoch in der Größenordnung von 2 bis 8 Bytes (oder zumindest deutlich kleiner als 256 Bytes), so dass Sie einen Pufferüberlauf haben. Sie möchten wahrscheinlich Fred (& Puffer, 1, 1, Datei) verwenden.

Außerdem schreiben Sie Byte-Daten in einen Int-Zeiger. Dies funktioniert bei einem Endian-Ness (in der Tat Small-Endian), so dass Sie mit der Intel-Architektur gut zurechtkommen werden und daraus schlechte Gewohnheiten lernen werden, wenn WILL eines Tages zurückkommt und Sie beißt.

Versuchen Sie wirklich, Byte-Daten nur in byte-organisierten Speicher zu schreiben, anstatt in Ints oder Floats.

0
Vatine