Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   untypisierte dateien (https://www.delphipraxis.net/150104-untypisierte-dateien.html)

khh 7. Apr 2010 13:28


untypisierte dateien
 
hallo zusammen,
ich steh grad auf dem Schlauch.

Ich hab ne Datei in der diverse Datensätze stehen.
jeder DS belegt 1024 Byte.
Wie würdet Ihr diese Sätze in eine Datei mit Feldtrennern überführen, damit diese später in eine DB geschrieben werden können.
Hab mall ne Ansatz mit blockread gefunden, denke aber das muss doch irgendwie einfacher zu bewerkstelligen sein.

Danke Gruss KH

Klaus01 7. Apr 2010 13:30

Re: untypisierte dateien
 
Hallo,

ich würde mir ein Record (mit den entsprechenden Feldern) bauen
und die Datensätze damit einlesen.

Grüße
Klaus

khh 7. Apr 2010 13:33

Re: untypisierte dateien
 
Zitat:

Zitat von Klaus01
Hallo,

ich würde mir ein Record (mit den entsprechenden Feldern) bauen
und die Datensätze damit einlesen.

Grüße
Klaus

also mit blockread die ganzen 1024 byte einlesen, aber wie dann weiter?

himitsu 7. Apr 2010 13:36

Re: untypisierte dateien
 
Zitat:

Zitat von khh
aber wie dann weiter?

Woher sollen wir das wissen?

Zitat:

Wie würdet Ihr diese Sätze in eine Datei mit Feldtrennern überführen
Vorallem ohne Kenntnis des Aufbaus dieser Blöcke.


Aber "einfach" die Daten in dan gewünschte Format konvertieren und neu abspeichern? :gruebel:


Entweder du ließt die Blöcke stückchenweise aus (also direkt die einzelnen Felder)
oder du erstellst dir einen Record, über welchen du diese Daten dann eventuell zerlegen könntest.

Klaus01 7. Apr 2010 13:41

Re: untypisierte dateien
 
nein, blcokread meinte ich nicht.

Ein Datensatz hat bestimmte Datenfelder.
Diese Felder kannst Du im Record nachbauen.
Delphi-Quellcode:
type
  TDatensatz = record
     NName : String[25];
     VName : String[25];
     ..
  end;


...

var
  datensatz: TDatensatz;
  datenFile: File of TDatensatz;

begin
  assignFile(..);
  reset(datenFile);
  while not eof(datenFile) do
    begin
      read(datenFile,datensatz);
      //verschiebe datensatz in Datenbank
      datensatz.NName -> Datenbank
      datensatz.VName -> Datenbank
   end;
  closeFile(datenFile);
end;
Grüße
Klaus

khh 7. Apr 2010 13:42

Re: untypisierte dateien
 
ich danke euch für den Ansatz.

Gruss KH

Bernhard Geyer 7. Apr 2010 21:42

Re: untypisierte dateien
 
Zitat:

Zitat von Klaus01
ich würde mir ein Record (mit den entsprechenden Feldern) bauen
und die Datensätze damit einlesen.

Sobald längere strings (unwahrscheilich) oder Unicode-Text beteiligt ist, wird das nicht mehr funktionieren.

DeddyH 8. Apr 2010 08:10

Re: untypisierte dateien
 
Zitat:

Zitat von khh
jeder DS belegt 1024 Byte.

Das klingt aber nicht danach.

khh 8. Apr 2010 08:33

Re: untypisierte dateien
 
Liste der Anhänge anzeigen (Anzahl: 1)
der DS ist nicht grösser als 1024 byte, aber der Zeichensatz, bzw. die Sonderzeichen machen Probleme.
Ich hänge hier mal eine Datei mit einem DS an.

Gruss KH

EDIT: ist keine txt datei, habe die Endung nur so vergeben, weil ne dat nicht hochzuladen ging.

Klaus01 8. Apr 2010 08:43

Re: untypisierte dateien
 
Guten Morgen,

hast Du auch eine Beschreibung zu dem Datensatz?

Grüße
Klaus

khh 8. Apr 2010 08:53

Re: untypisierte dateien
 
Zitat:

Zitat von Klaus01
Guten Morgen,

hast Du auch eine Beschreibung zu dem Datensatz?

Grüße
Klaus

leider nein, die Daten stammen aus eine uraltprogramm.
Ich brauch nur den Namen, also im Beispiel "Mailänder-Schnitte" , die Artikelnr "102" und den Preis 1.200

DeddyH 8. Apr 2010 08:56

Re: untypisierte dateien
 
Wurden die Daten evtl. unter DOS angelegt? Dann könnte eine Umwandlung mit OEMToChar helfen.

khh 8. Apr 2010 08:57

Re: untypisierte dateien
 
Zitat:

Zitat von DeddyH
Wurden die Daten evtl. unter DOS angelegt? Dann könnte eine Umwandlung mit OEMToChar helfen.

ja ist ein altes DOS-Programm
EDIT: heisst dann ich muss byte für byte mit oemtochar durchgehen?

DeddyH 8. Apr 2010 09:14

Re: untypisierte dateien
 
Nein, OEMToChar verarbeitet ganze Strings.

khh 8. Apr 2010 09:25

Re: untypisierte dateien
 
ich hab jetzt
mit:

Delphi-Quellcode:
    read(f,datensatz);
    test:=datensatz.zeile;
    name := datensatz.name;
    oemtochar(PChar(test),PChar(test2));
    oemtochar(PChar(name),PChar(name2));
die ersten 100 byte eingelesen, wobei Zeile 75 byte und Name 25 byte gross ist.

Leider steht in test nach dem lesen nix drin.
in name steht "il?nderschnitte" und nach der Konvertierung mit oemtochar nur noch ein Leerstring :-(

[edit=mkinzler]Delphi-Tag eingefügt Mfg, mkinzler[/edit]

khh 8. Apr 2010 09:50

Re: untypisierte dateien
 
gibts den keine Möglichkeit die einzelnen bytes direkt zu lesen?
Ich weiss ja an welcher Stelle die stehen, dann könnte man die evtl. direkt lesen?

DeddyH 8. Apr 2010 10:04

Re: untypisierte dateien
 
Du könntest die Datei z.B. in einen TMemoryStream laden und dessen Methoden dann anwenden (Seek, Read, ReadBuffer, etc.).

khh 8. Apr 2010 10:07

Re: untypisierte dateien
 
Zitat:

Zitat von DeddyH
Du könntest die Datei z.B. in einen TMemoryStream laden und dessen Methoden dann anwenden (Seek, Read, ReadBuffer, etc.).

klingt gut, werd ich mir dessen Methoden mal genauer anschaun.

Danke

p80286 8. Apr 2010 10:20

Re: untypisierte dateien
 
Zunächst würde mich mal interessieren wo dieses seltsame "OEMtoChar" herkommt. in meiner Onlinehile finde ich da nichts.
Ich hätte Dir empfolen alle Zeichen eines Textfeldes über eine Übersetzungstabelle zu jagen und alles wäre gut. Insbesonders da einige alte DOS-Programme teilweise eine etwas eigenwillige/exotische Zeichentabelle genutzt haben.

wie sieht eigentlich die Definition von Datensatz aus?

Ich hab es übrigens in der Vergangenheit so gehalten, das ich das Einlesen über ein Array [0..x] of Char/Byte erledigt habe und darüber ein Record mit den richtigen Feld/Datendefinitionen gelegt habe:
Delphi-Quellcode:
type
  tMyrecord = packed record
       f1 : array [0..$4A] of byte;
       name : array [$4B..$63] of char;
       trenn1: byte;
       rest : array [$65..$3FF];
   end;

var
  buffer : array [0..1023] of char;
  myrecord : tMyrecord absolute buffer;
  gelesen : integer;
...
fs:=tfilestream.create(.......);
gelesen:=fs.read(buffer,sizeof(buffer));
...
und dann entweder im Debugger anschauen was in dem Record steht, oder eine Printausgabe machen oder ....

Und erst wenn Du eine vernünftige Datenstruktur hast, dann erst an der Darstellung drehen, es könnte sonst sein, daß Du irgendwelche Bytes als Char interpretierst.

Gruß
K-H

Edit:
Tippfehler
Warum zum Teufel wollen hier so viele immer wieder eine Datei Byte für Byte einlesen?
Je größer die Datenmenge, die man liest, desto fixer geht alles. Ich versteh das nicht!

DeddyH 8. Apr 2010 10:24

Re: untypisierte dateien
 
Zitat:

Zitat von p80286
Zunächst würde mich mal interessieren wo dieses seltsame "OEMtoChar" herkommt. in meiner Onlinehile finde ich da nichts.

MSDN-Library durchsuchenOEMToChar

khh 8. Apr 2010 10:43

Re: untypisierte dateien
 
Zitat:

wie sieht eigentlich die Definition von Datensatz aus?
die gibts leider nicht :-(

[edit=mkinzler]Tag gefixt Mfg, mkinzler[/edit]

p80286 8. Apr 2010 11:06

Re: untypisierte dateien
 
@DeddyH
Danke! war mir entfallen.

Zitat:

Zitat von khh
ich hab jetzt
mit:

Delphi-Quellcode:
    read(f,datensatz);
    test:=datensatz.zeile;
    name := datensatz.name;
    oemtochar(PChar(test),PChar(test2));
    oemtochar(PChar(name),PChar(name2));

Hiernach hatte ich angenommen, daß "Datensatz" ein Record sei?

Gruß
K-H

khh 8. Apr 2010 11:25

Re: untypisierte dateien
 
Zitat:

Zitat von p80286
@DeddyH
Danke! war mir entfallen.

Zitat:

Zitat von khh
ich hab jetzt
mit:

Delphi-Quellcode:
    read(f,datensatz);
    test:=datensatz.zeile;
    name := datensatz.name;
    oemtochar(PChar(test),PChar(test2));
    oemtochar(PChar(name),PChar(name2));

Hiernach hatte ich angenommen, daß "Datensatz" ein Record sei?

Gruß
K-H

ist ja auch richtig
ich hab einfach einen Record definiert, insgesamt 1024 byte gross,
habe die einzelnen Werte die ich brauche definiert(sieht man ja im File wo die stehen, und den Rest wie zb "zeile" gelesen und "weggeworfen".
Leider funktioniert das so nicht, wie ich schon oben erwähnte.

test habe ich nur testweise gelesen um zu sehen was nach oemtochar "rüberkommt".
Endgültig brauche ich nur artnr bezeichnung und preis, welche an festen Stellen im DS stehen.


also datensatz.name 25 byte gross, datensatz.nr 3 byte gross und datensatz.preis 8 byte gross.

khh 8. Apr 2010 12:41

Re: untypisierte dateien
 
Zitat:

Zitat von p80286
Delphi-Quellcode:
type
  tMyrecord = packed record
       f1 : array [0..$4A] of byte;
       name : array [$4B..$63] of char;
       trenn1: byte;
       rest : array [$65..$3FF];
   end;

var
  buffer : array [0..1023] of char;
  myrecord : tMyrecord absolute buffer;
  gelesen : integer;
...
fs:=tfilestream.create(.......);
gelesen:=fs.read(buffer,sizeof(buffer));
...
und dann entweder im Debugger anschauen was in dem Record steht, oder eine Printausgabe machen oder

ich komme der Sache näher, so funktionierts "fast" :-)

bis auf die Umlaute krieg ich die richtige Bezeichnung, aber oemtochar bringt leider nix :-(

DeddyH 8. Apr 2010 13:03

Re: untypisierte dateien
 
Liste der Anhänge anzeigen (Anzahl: 2)
Ich hab mal alles bis auf die Bezeichnung aus der Datei rausgeworfen und mit folgendem Code getestet:
Delphi-Quellcode:
var sl: TStringlist;
    s: string;
begin
  sl := TStringlist.Create;
  try
    sl.LoadFromFile('E:\muster.txt');
    s := sl[0];
    OemToChar(PChar(s),PChar(s));
    ShowMessage(s);
  finally
    sl.Free;
  end;
end;
Sieht einwandfrei aus (siehe Anhang).

khh 8. Apr 2010 13:46

Re: untypisierte dateien
 
Zitat:

Zitat von DeddyH
Ich hab mal alles bis auf die Bezeichnung aus der Datei rausgeworfen und mit folgendem Code getestet:
Delphi-Quellcode:
var sl: TStringlist;
    s: string;
begin
  sl := TStringlist.Create;
  try
    sl.LoadFromFile('E:\muster.txt');
    s := sl[0];
    OemToChar(PChar(s),PChar(s));
    ShowMessage(s);
  finally
    sl.Free;
  end;
end;
Sieht einwandfrei aus (siehe Anhang).

sieht wirklich gut aus, muss ich mal sehen ob ich noch wo nen Fehler drin hatte ;-)

DeddyH 8. Apr 2010 13:50

Re: untypisierte dateien
 
Vielleicht SetLength() für den Zielstring vergessen? Ich benutze ja 2 mal dieselbe Stringvariable im Gegensatz zu Deinem Code.

khh 8. Apr 2010 13:58

Re: untypisierte dateien
 
Zitat:

Zitat von DeddyH
Vielleicht SetLength() für den Zielstring vergessen? Ich benutze ja 2 mal dieselbe Stringvariable im Gegensatz zu Deinem Code.

werd das später nochmal in Ruhe durchchecken, muus jetzt erst mal noch was anderes machen.
ich danke euch bis hierhin, melde mich sicher nochmal.

khh 9. Apr 2010 08:09

Re: untypisierte dateien
 
hallo zusammen,
das mit den Umlauten funktioniert zwar noch nicht, aber das ist erst mal zweitrangig.

Das Einlesen des einen DS aus dem Beispiel funktioniert und zwar folgendermassen:

Delphi-Quellcode:
tMyrecord = packed record
       f1 : array [0..$36] of byte;
       artnr: array [$37..$3C] of char;
       f2 : array [$3D..$4A] of byte;
       name : array [$4B..$63] of char;
       trenn1: byte;
       name2 : array [$65..$7D] of char;
       f3 : array [$7F..$DF] of byte;
       preis : array [$E0..$E6] of char;
       rest : array [$E7..$3FF] of char;
   end;

   
var
  buffer : array [0..1024] of char;
  myrecord : tMyrecord absolute buffer;
  gelesen : integer;
  FS: TFileStream;
  test1, test2, test3, test4: string;

begin
fs:=tfilestream.create('muster.txt', fmOpenRead);

gelesen:=fs.read(buffer,sizeof(buffer));
 test1:= myrecord.artnr ;
 test2:= myrecord.name ;
 test3:= myrecord.name2 ;
 test4:= myrecord.preis ;
Die vollständige Datei hat aber 557056 byte , also 544 DS.
die lassen sich zwar vollständig in den Buffer lesen, (buffer : array [0..557056] of char;) aber wie komm ich an die positionen ran?
ne while eof geht ja auchnicht :-(
EDIT: ich könnte ja 544 files draus machen, aber sicher geht das einfacher, oder?
Danke für eure Hilfe.

Klaus01 9. Apr 2010 08:16

Re: untypisierte dateien
 
Guten Morgen,

der "Lesezeiger, bzw. Leseposition" ändert sich nach jedem Lesevorgang.
Liest Du jeweils immer einen Datensatz ein steht der Lesezeiger auf dem nächsten Byte hinter dem
Datensatz. Liest Du einen weiteren Datensatz fängt der Lesevorgang an der Position an wo der Lesezeiger
hinzeigt.

Die Anzahl der Datensätze erhälst Du so: Stream.size div Datensatzgröße.

Grüße
Klaus

khh 9. Apr 2010 08:38

Re: untypisierte dateien
 
Zitat:

Zitat von Klaus01
Guten Morgen,

der "Lesezeiger, bzw. Leseposition" ändert sich nach jedem Lesevorgang.
Liest Du jeweils immer einen Datensatz ein steht der Lesezeiger auf dem nächsten Byte hinter dem
Datensatz. Liest Du einen weiteren Datensatz fängt der Lesevorgang an der Position an wo der Lesezeiger
hinzeigt.

Die Anzahl der Datensätze erhälst Du so: Stream.size div Datensatzgröße.

Grüße
Klaus

hallo Klaus, heisst ich lese die komplette Datei einfach 544 mal?

Klaus01 9. Apr 2010 08:41

Re: untypisierte dateien
 
Zitat:

Zitat von khh
Zitat:

Zitat von Klaus01
Guten Morgen,

der "Lesezeiger, bzw. Leseposition" ändert sich nach jedem Lesevorgang.
Liest Du jeweils immer einen Datensatz ein steht der Lesezeiger auf dem nächsten Byte hinter dem
Datensatz. Liest Du einen weiteren Datensatz fängt der Lesevorgang an der Position an wo der Lesezeiger
hinzeigt.

Die Anzahl der Datensätze erhälst Du so: Stream.size div Datensatzgröße.

Grüße
Klaus

hallo Klaus, heisst ich lese die komplette Datei einfach 544 mal?

Nein, Du liest die Datei einmal in den FileStream ein.
In diesem Stream kannst Du dann 544 mal lesen bis Du zum Streamende ankommst.

Grüße
Klaus

khh 9. Apr 2010 08:50

Re: untypisierte dateien
 
Zitat:

Zitat von Klaus01
Zitat:

Zitat von khh
Zitat:

Zitat von Klaus01
Guten Morgen,

der "Lesezeiger, bzw. Leseposition" ändert sich nach jedem Lesevorgang.
Liest Du jeweils immer einen Datensatz ein steht der Lesezeiger auf dem nächsten Byte hinter dem
Datensatz. Liest Du einen weiteren Datensatz fängt der Lesevorgang an der Position an wo der Lesezeiger
hinzeigt.

Die Anzahl der Datensätze erhälst Du so: Stream.size div Datensatzgröße.

Grüße
Klaus

hallo Klaus, heisst ich lese die komplette Datei einfach 544 mal?

Nein, Du liest die Datei einmal in den FileStream ein.
In diesem Stream kannst Du dann 544 mal lesen bis Du zum Streamende ankommst.

Grüße
Klaus

ja so hab ichs gemeint, hab mich falsch ausgedrückt ;-)

p80286 9. Apr 2010 09:08

Re: untypisierte dateien
 
Du machst eseinfach so:
Delphi-Quellcode:
....

repeat
  gelesen:=fs.read(buffer,sizeof(buffer));
  if gelesen:=sizeof(buffer) then begin    { nur vollständig gefüllte Sätze verarbeiten }
    { Daten verarbeiten }
    test1:= myrecord.artnr ;
    test2:= myrecord.name ;
    test3:= myrecord.name2 ;
    test4:= myrecord.preis ;
  end;
until gelesen<sizeof(buffer);              { wenn nicht mehr genügend Daten gelesen werden ist schluß!}

...
Der Test von gelesen ist wichtig, da es keine Fehlermeldung bei Dateiende,fehlender zugriffsbereichtigung etc. gibt!

Gruß
K-H

khh 9. Apr 2010 09:41

Re: untypisierte dateien
 
ich danke euch
EDIT : auch das oemtochar zeigt Wirkung, sprich Umlaute funktionieren.
War tatsächlich das fehlende SetLength.


Gruss KH


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz