Aus mehreren Files blockweise lesen

Ein vereinfachtes Beispiel um die Daten aus mehreren Files blockweise zu lesen und zu bearbeiten.

Buffer um die Daten aus dem File zu lesen:

typedef struct
{
	// Wir nehmen an, unsere Daten haben folgende Struktur:
	char F1n_SatzLaenge [4]; // Satzlänge, z.B. "0128"
	char F2a_SatzArt    [1]; // Satzart, z.B. 'A', 'C' oder 'E'
	char x_Rest       [123]; // Damit die Gesamtgröße immer 128 Byte bleibt
} FILE_SATZ_BUFFER;

Aus diesen Files soll gelesen werden (globale Variablen):

FILE * file1 = NULL; // Das 1. File
FILE * file2 = NULL; // Das 2. File

Eine Beispielsfunktion, die versucht, mehrere Files (auf einheitliche Weise) zu bearbeiten:

int app_Run (int rc_Init)
{
	int rc = RC_OK;
 
	// Beide Eingangsdateien sollen bearbeitet werden.
	if (rc == RC_OK) rc = auswertenFile(&file1); // Das 1. File
	if (rc == RC_OK) rc = auswertenFile(&file2); // Das 2. File
 
	return rc;
} // app_Run()

Die Funktion ruft für jedes einzelne File eine weitere Funktion auf, die nur für die Bearbeitung eines einzelnes Files zuständig ist.

Folgende (Beispiel-)Funktion bearbeitet ein (als Parameter übergebene) File:

int auswertenFile (const FILE ** fileZumAuswerten)
{
	int rc = RC_OK;
	FILE_SATZ_BUFFER satzBuffer;
 
	memset(&satzBuffer, '\0', sizeof(satzBuffer));
 
	// Validierung: Vorhandensein von Variablen (darf kein NULL sein)
	if (!fileZumAuswerten) rc = RC_ERROR;
	// Validierung: Pointer-Variablen: Werte nur im definierten Bereich
	if (fileZumAuswerten) if (!(*fileZumAuswerten)) rc = RC_ERROR; // File MUSS bereits geöffnet sein
 
	if (rc) fprintf(stderr, "auswertenFile(): Validierungsfehler.\n");
 
	if (rc == RC_OK)
	{
		while (!feof(*fileZumAuswerten) && !rc) // Solange das File das EOF noch nicht erreicht hat, in der Schlefe lesen.
		{
			rc = getDataBlock(*fileZumAuswerten, &satzBuffer); // Einen Block aus dem File lesen und im Buffer speichern.
 
			// TODO: Weitere Aktivitäten mit den Daten.
			// TODO: Weitere Aktivitäten mit den Daten.
		} // while()
	} // if
 
	return rc;
} // auswertenFile(..)

Da das File zu groß sein kann, als der zur Verfügung stehende Speicher, und weil seine Struktur nicht zwangsläufig homogen sein sollte, macht es oft Sinn, das File nicht auf einmal, sondern blockweise (evtl. sogar mit verschiedenen Lesefunktionen) zu lesen. Das schafft Flexibilität beim Lesen.

Folgende (Beispiel-)Funktion liest einen Block und gibt ihn im Buffer zurück:

int getDataBlock (const FILE * fileZumLesen, FILE_SATZ_BUFFER * satzBuffer)
{
	int rc = RC_OK;
	int blkGelesen = 0;
 
	blkGelesen = fread(satzBuffer, sizeof(FILE_SATZ_BUFFER), 1, fileZumLesen); // 1 Block lesen
	if (blkGelesen != 1) rc = RC_ERROR;
 
	// TODO: Weitere Aktivitäten mit den Daten, bevor sie zurückgegeben werden.
 
	return rc;
} // getDataBlock(..)

:!: Achtung: Die Funktionen fread() und fwrite() sind plattformabhängig und nicht portabel! Man soll darauf achten, daß der schreibende und der lesende Prozesse binär zu einander kompatibel sind. Das heißt, sie haben das gleiche Alignment (plattform- und compilerabhängig) und die selbe Architektur (Byte-Reihenfolge im Sinne von Big- und Little-Endian).


Stand: 04.03.2010
: Jürgen Kreick

EOF