Gezielter Zugriff auf Teile einer großen Datei

Hallo an alle Experten,

Ich brauche dringend eine Programmroutine, die folgendes macht:
(Programmsprache ist egal, sollte aber selbstablaufemd sein nach Aufruf von einem anderen Programm aus)

Ich habe eine Datendatei z.B. 1.dat auf einer CD mit ca 10 000 Daten (Zahlen, in ASCII oder HEX).
Daten 0 bis 999 sind für Fall A, 1000 bis 1999 für Fall B usw…

Ein Programm übergibt den gewählten Fall, z. B. Fall E, dann wird aus 1.dat der Bereich 4000 bis 4999 gelesen, eine neue Datei X.dat erzeugt (temporär in z.B C:\windows\temp) , welche nur jene Daten von Fall E enthält.

Datei X.dat wird von anderen Programm gelesen und danach gelöscht.

Ich danke für jegliche Hilfe.

Gruß Lutz

Moin,

(Zahlen, in ASCII oder HEX).

Klingt nach Perl.

Ein Programm übergibt den gewählten Fall, z. B. Fall E, dann
wird aus 1.dat der Bereich 4000 bis 4999 gelesen, eine neue
Datei X.dat erzeugt (temporär in z.B C:\windows\temp) , welche
nur jene Daten von Fall E enthält.

Kein wirkliches Problem, Dein Programm muß nur noch wissen, welche Bereiche zu welchem Fall gehören. Dann beide Dateien öffnen, seek, X Fälle lesen/schreiben, beide Dateien schließen.

Thorsten

Hallo Thorsten,

klingt ganz gut, aber ich habe von Perl überhaupt keine Ahnung.
Könntest Du mir bitte die paar Programmzeilen aufschreiben und z.B zumailen ?
Wie kann ich das dann umsetzen und abspeichern ?

Ich habe konkret 63 Fälle mit je 38906 Zahlen, also 2 541 078 insgesamt.
Wäre nett, wenn Du Dich nochmal melden könntest.

Gruß Lutz

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Moin,

klingt ganz gut, aber ich habe von Perl überhaupt keine
Ahnung.

Dann nimm halt irgendeine andere Sprache.

Könntest Du mir bitte die paar Programmzeilen aufschreiben und
z.B zumailen ?

Ein paar mehr als ein paar sind das schon, zumal ich von den Daten nichts weiß. Da mußt Du Dich schon selbst bemühen.

Thorsten

Ein Programm übergibt den gewählten Fall, z. B. Fall E, dann
wird aus 1.dat der Bereich 4000 bis 4999 gelesen, eine neue
Datei X.dat erzeugt (temporär in z.B C:\windows\temp) , welche
nur jene Daten von Fall E enthält.

Ich habe konkret 63 Fälle mit je 38906 Zahlen, also 2 541 078
insgesamt.

Also, in C wäre das in etwa so (fall hat hier nicht A, B, C… sondern 1, 2, 3… ein umrechnen von A nach 1 usw. dürftest du aber hinbekommen, z.B. über den ASCII-Wert) :

void copycasetofile(int fall)
{
FILE *source, *target;
char buf[38906];
long pos = (fall - 1) * 38906;

source = fopen(„1.dat“, „rb“);
target = fopen(„c:\windows\temp\out.dat“, „wb“);

fseek(source, pos, SEEK_SET);
fread(buf, 1, 38906, source);
fwrite(buf, 1, 38906, target);

fclose(source);
fclose(target);
}

Sieht für mich schwierig aus, aber wenn diese Zeilen funktionieren — warum nicht ? Ich danke Dir !

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Okay, wenn du C nicht so gut kannst, dann hier mal ne kurze Erklärung dazu :

void copycasetofile(int fall)

Funktionsname copycasrtofile - kann beliebig heissen
void vor Funktionsname - sagt aus, daß Funktion keinen Rückgabewert hat
int fall - Variable „fall“ vom Typ int (ganze zahlen)

{

Funktionsanfang

FILE *source, *target;

zwei Dateivariablen

char buf[38906];

der Puffer, in den gelesen wird, von der benötigten Größe

long pos = (fall - 1) * 38906;

variable POS inkl. Berechnung, an welcher Stelle die betroffenen
Daten in der Datei anfangen

source = fopen(„1.dat“, „rb“);
target = fopen(„c:\windows\temp\out.dat“, „wb“);

öffnen der beiden Dateien

fseek(source, pos, SEEK_SET);

„vorspulen“ auf die gesuchte Stelle

fread(buf, 1, 38906, source);

Lesen von 38906 Zahlen aus Datei in Puffer

fwrite(buf, 1, 38906, target);

schreiben des puffers in Zieldatei

fclose(source);
fclose(target);

beide Dateien schließen

}

Funktionsende

So, viel Spaß beim abtippen :smile:

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Okay, ich probiere es. Danke ! (o.T.)

Okay, wenn du C nicht so gut kannst, dann hier mal ne kurze
Erklärung dazu :

void copycasetofile(int fall)

Funktionsname copycasrtofile - kann beliebig heissen
void vor Funktionsname - sagt aus, daß Funktion keinen
Rückgabewert hat
int fall - Variable „fall“ vom Typ int (ganze zahlen)

{

Funktionsanfang

FILE *source, *target;

zwei Dateivariablen

char buf[38906];

der Puffer, in den gelesen wird, von der benötigten Größe

long pos = (fall - 1) * 38906;

variable POS inkl. Berechnung, an welcher Stelle die
betroffenen
Daten in der Datei anfangen

source = fopen(„1.dat“, „rb“);
target = fopen(„c:\windows\temp\out.dat“, „wb“);

öffnen der beiden Dateien

fseek(source, pos, SEEK_SET);

„vorspulen“ auf die gesuchte Stelle

fread(buf, 1, 38906, source);

Lesen von 38906 Zahlen aus Datei in Puffer

fwrite(buf, 1, 38906, target);

schreiben des puffers in Zieldatei

fclose(source);
fclose(target);

beide Dateien schließen

}

Funktionsende

So, viel Spaß beim abtippen :smile:

Noch was !
Hoi !

Mir fällt gerade auf, daß die Zeile

long pos = (fall - 1) * 38906;

falsch ist. Es muß heißen :

long pos = ((fall - 1) * 38906) + 1;

Desweiteren ist es noch wichtig, WIE die Zahlen abgespeichert sind. So, wie es hier steht, liest das PGM 38906 Charakter-Variablen (also 8 Bit-Zahlen) - wenn es sich um größere Zahlenvariablen handelt, musst du ggf. die Datentypen hier ändern:

char buf[38906];

Dann muss aber auch die Größe hier geändert werden - im
Moment würden 38906 mal EIN Byte gelesen/geschrieben.

fread(buf, 1, 38906, source);
fwrite(buf, 1, 38906, target);

Die „1“ muss dann geändert werden in die Anzahl der tatsächlichen Bytes pro Zahl - am besten arbeitet man hier
mit der Funktion sizeof() :

fread(buf, sizeof(buf[0]), 38906, source);
fwrite(buf, sizeof(buf[0]), 38906, target);

-)