![]() |
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Bei einem
Delphi-Quellcode:
gibt es Index-Dateien?
File of Record
Aber nur wenn man die selber gebaut hat und zum Auslesen sind die dann auch nicht wichtig |
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Gerade bei Records gibt es die Index-Daeien. .
|
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Also mir ist auch neu, das es Indexdateien gibt. Zumindest finde ich sie nicht.
Dessenungeachtet würde ich einen vollständig anderen Ansatz verfolgen, der sämtliche eventuell vorhandenen Inkompatibilitäten ausräumt: Lies die Daten per Stream ein:
Delphi-Quellcode:
Auf diese Weise kann man sich Byte für Byte an die Richtige Einleseroutine herantasten. Bei mir hat das so immer geklappt. Ich habe es nämlich nicht hinbekommen, alle Auffüllbytes (word-alignment) mit einem Record richtig hinzubekommen. Aber das waren auch Daten von einer Siemenssteuerung, soweit ich mich erinnere.
Procedure TMyRecord.Read(aStream : Stream);
Begin myByte := aStream.ReadByte; myInteger := aStream.ReadIntger; myString := aStream.ReadAnsiString(bytesToRead); // Wäre denkbar, das ein String Wortweise abgelegt wird, d.h. wenn der String eine ungerade Anzahl // An Zeichen hat, wird mit einem Byte aufgefüllt if Odd(Length(myString)) then aStream.ReadByte; mySecondByte := aStream.ReadByte; mySubRecord := mySubRecord.Read(aStream); myPadding := aStream.ReadByte; End; Na auf jeden Fall ist o.g. Verfahren idiotensicher und führt immer zum Erfolg. PS: Ich glaube nicht, das ein Stream Methoden wie 'ReadByte, ReadString, ReadInteger' hat, aber die kann man sich leicht selbst als Class Helper bauen. |
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Zitat:
Delphi-Quellcode:
und Index-dateien gearbeitet haben, vielleicht meint er so etwas.
File of Record
Gruß K-H |
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
.. hast Du dir die Daten schonmal mit einem HexViewer (HxD) angeschaut?
Kannst Du dann ein sich wiederholendes Muster erkennen? Grüße Klaus |
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Hallo zusammen,
klasse welche Resonanz da erzeugt wird:thumb:! Kurz zu den Fragen/Antworten bezgl. Index-Dateien: Nein, es sind ganz normal über TP6 erzeugte typisierte, einzelne, Dateien. Index-Dateien gibt es dazu nicht - das gehört in's Datenbankfach. Und - wie schon erwähnt - eine Datei enthält immer nur einen Record (einen einzigen Datensatz des betreffenden Typs). Ich denke ich werde mich in Richtung der Streams (@Dejan Vu: Danke für den Vorschlag) bewegen. Ich teste im Moment noch verschiedene Typzusammenstellungen des Records und das mit ALIGN ON/OFF und PACKED (will mal wissen, ob das etwas bringt). Wenn ich da Ergebnisse habe, melde ich mich wieder. Grüsse, Warp |
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Zitat:
|
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Also,
hier ein paar Ergebnisse. Ich habe das jetzt allerdings nur auf einer Win 7 VM, 32 Bit, mit XE2 testen können: Versuch 1: T_Settings_XE4 = Packed Record ID: Byte; Baud: Byte; Line: Byte; TSN1: Byte; TSN2: Byte; TSN3: Byte; TSN4: Byte; TSN5: Byte; TSN6: Byte; Description: ShortString; ConnectionDef: ShortString; end; Ergibt: Daten passen, Zeichenfolge wie gewünscht. (Keine Ahnung warum das gestern mit meinen XE4 Tests daneben ging ...) Versuch 2: {$H-} T_Settings_XE4 = Record ID: Byte; Baud: Byte; Line: Byte; TSN1: Byte; TSN2: Byte; TSN3: Byte; TSN4: Byte; TSN5: Byte; TSN6: Byte; Description: String[255]; //Dieser String[255] wird durch vorheriges {$H-} wie ein TP6 String behandelt (nur Win 32 Bit!!) ConnectionDef: String[255]; end; {$H+} Zu {$H-} noch Auszug aus Delphi Online Hilfe: "Auf der Win32-Plattform können Sie mit der Direktive {$H-}string in ShortString umwandeln. Dieses Vorgehen ist möglicherweise bei der Verwendung von älterem 16-Bit-Delphi-Code oder Turbo-Pascal-Code mit aktuellen Programmen hilfreich." Ergibt: = Das passt ebenso, die Daten werden passend übergeben, Zeichenfolge wie gewünscht. @Hansa Ja - toll. Ist aber nicht als Witz gemeint. Es ist damals so gemacht worden (so Anfang der 90er) und die Frage nach dem Inhalt (Datensätze) pro Datei war ja vorher im Thread gestellt worden (=> Antwort geben). Was mach ich jetzt daraus (nach aktuellem Stand der Dinge): Ich denke ich werde auf dieser Basis die Daten konvertieren in ein anderes Format, ggf. aber den Streams auch eine Chance geben (ist so schön flexibel) Schöne Grüsse, Warp |
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Ich würde dir empfehlen eine abstrakte Klasse zu bauen, wo die konkreten Ableitungen jeweils die alten und neuen Varianten kapseln.
Bei geschickter Implementierung kannst du mit
Delphi-Quellcode:
deine Daten konvertieren und auch in Zukunft noch die alten Daten lesen und (prinzipiell) sogar noch schreiben.
FooNew.Assign( FooOld );
Delphi-Quellcode:
Implementierung eines alten Daten-Records
// Der abstrakte Teil, der auch immer wieder erweitert wird, und den aktuellen Stand repräsentiert
unit Settings; interface uses System.Classes; type TSettings = class abstract( TPersistent ) private procedure AssignToSettings( Dest: TSettings ); protected // der Getter kann hier auch virtuell implementiert werden // damit bei neuen Eigenschaften wenigstens ein Default-Wert // übermittelt wird, wenn der in den alten Informationen // gar nicht verfügbar oder ableitbar ist function GetBaud: Byte; virtual; abstract; procedure SetBaud( const Value: Byte ); virtual; abstract; procedure AssignTo( Dest: TPersistent ); override; public property Baud: Byte read GetBaud write SetBaud; end; implementation { TSettings } procedure TSettings.AssignTo( Dest: TPersistent ); begin if Dest is TSettings then AssignToSettings( Dest as TSettings ) else inherited; end; procedure TSettings.AssignToSettings( Dest: TSettings ); begin Dest.SetBaud( Self.GetBaud ); end; end.
Delphi-Quellcode:
Implementierung eines neuen Daten-Objekts
unit Settings.v1_0;
interface uses Settings; type T_Settings_XE4 = Packed Record ID: Byte; Baud: Byte; Line: Byte; TSN1: Byte; TSN2: Byte; TSN3: Byte; TSN4: Byte; TSN5: Byte; TSN6: Byte; Description: ShortString; ConnectionDef: ShortString; end; TSettings_V1_0 = class( TSettings ) private FData: T_Settings_XE4; protected function GetBaud: Byte; override; procedure SetBaud( const Value: Byte ); override; public constructor Create( Data: T_Settings_XE4 ); end; implementation { TSettings_V1_0 } constructor TSettings_V1_0.Create( Data: T_Settings_XE4 ); begin inherited Create; FData := Data; end; function TSettings_V1_0.GetBaud: Byte; begin Result := FData.Baud; end; procedure TSettings_V1_0.SetBaud( const Value: Byte ); begin FData.Baud := Value; end; end.
Delphi-Quellcode:
ein kleiner Test zum Hin- und Herumschubsen der Daten
unit Settings.v2_0;
interface uses Settings; type T_Settings_Data = class private FBaud: Integer; public property Baud: Integer read FBaud write FBaud; end; TSettings_v2_0 = class( TSettings ) private FData: T_Settings_Data; FOwnsObject: Boolean; protected function GetBaud: Byte; override; procedure SetBaud( const Value: Byte ); override; public constructor Create( Data: T_Settings_Data; OwnsObject: Boolean = True ); destructor Destroy; override; end; implementation { TSettings_v2_0 } constructor TSettings_v2_0.Create( Data: T_Settings_Data; OwnsObject: Boolean ); begin inherited Create; FData := Data; FOwnsObject := OwnsObject; end; destructor TSettings_v2_0.Destroy; begin if FOwnsObject then FData.Free; inherited; end; function TSettings_v2_0.GetBaud: Byte; begin Result := FData.FBaud; end; procedure TSettings_v2_0.SetBaud( const Value: Byte ); begin FData.FBaud := Value; end; end.
Delphi-Quellcode:
In der Anwendung selber würde ich immer mit
program dp_182543;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, Settings in 'Settings.pas', Settings.v1_0 in 'Settings.v1_0.pas', Settings.v2_0 in 'Settings.v2_0.pas'; procedure Main; var LOldSetting: T_Settings_XE4; LNewSetting: T_Settings_Data; LSettingOld, LSettingNew: TSettings; begin // die try..finally Blöcke habe ich der Übersichtlichkeit halber weggelassen! LOldSetting.Baud := 24; // Wert im alten Format gespeichert LSettingOld := TSettings_V1_0.Create( LOldSetting ); // Wrapper drumherum LNewSetting := T_Settings_Data.Create; // neues Format LSettingNew := TSettings_v2_0.Create( LNewSetting ); // Wrapper drumherum LSettingNew.Assign( LSettingOld ); // einfach zuweisen Writeln( LNewSetting.Baud ); // und schon ist auch im neuen Format der Wert :o) end; begin try Main; except on E: Exception do Writeln( E.ClassName, ': ', E.Message ); end; end.
Delphi-Quellcode:
arbeiten, weil es dann egal ist, wie und woher die Einstellungen denn nun wirklich kommen.
TSettings
|
AW: Turbo Pascal 6 erzeugte Dateien mit Delphi XE4 lesen
Also echt pro Datensatz eine Extra-Datei ? Ja, dann stellt sich die Frage nach Indexdateien in der Tat nicht. Ich würde, die betreffenden Dateien zuerst einmal in separates Unterverzeichnis isolieren, wo sonst nichts ist und dann eben mühselig per FindFirst/Findnext die Dateien lesen und den Inhalt zeilenweise in Textdatei übertragen. Aus der Textdatei würde ich dann die daten in SQL-datenbank übernehmen im Stile von :
Delphi-Quellcode:
DbNeutable.FieldByname ('NR').Asinteger := StrToInt (AltesFeld);
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:06 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