Tworzenie pliku .dat z konkretną zawartością

0

Potrzebuję dodać do swojego programu opcję tworzenia pliku .dat, który będzie używany przez inny program. Plik musi mieć konkretny wsad lecz muszę mieć opcję zmiany kilku komórek.

Wersja testowa na razie wygląda tak:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
 type

  TRecord = packed record
   A : Byte;
   B : Byte;
   C : Byte;
   D : Byte;
   E : Byte;
   Im : String[23];
   Op :  String[6];
   G : Byte;
  end;

procedure TForm1.Button1Click(Sender: TObject);

var
  F: file of TRecord;
  Rec : TRecord;
  s, s1, s2               : string;
  i :Integer;

begin

  s:= trim(Edit1.Text);
  s1:= trim(Edit2.Text);
  s2:= trim(Edit3.Text);

   Rec.A := 33;
   Rec.B := 00;
   Rec.C := 00;
   Rec.D := 00;
   Rec.E := 23;
   Rec.Im := (s + s1);
   Rec.Op := '0' +s2;
   Rec.G := 70;
   AssignFile(F, 'File.dat');
  try
    Rewrite(F);
    Write(F, Rec);
  finally
    CloseFile(F);
  end;
end;

end.

Taki plik obecnie tworzy mi program:

user image
user image

Na obrazku zaznaczone pola w których musiałaby się znajdować wartość 00 lub 01,(222222222222222 33333333 44444 - to wartości, które chcę zmieniać przed tworzeniem pliku)
W kodzie znajduje się '0' - Nie wiedziałem jak zmienić to na wartość 00 bo 'null' nie działa

Tak powinien wyglądać poprawnie wygenerowany plik:

user image

Wszystko byłoby ok gdyby nie fakt że zmienna String tworzy przed docelowym rekordem Bit (Obrazek 1 zaznaczone na czerwono), którego nie potrafię zmienić a bez zmiany program błędnie interpretuje plik .dat

Ma ktoś jakiś pomysł co można zmienić by plik był generowany poprawnie?

Będę wdzięczny za podpowiedź.

Pozdrawiam

0

Wszystko byłoby ok gdyby nie fakt że zmienna String tworzy przed docelowym rekordem Bit (Obrazek 1 zaznaczone na czerwono), którego nie potrafię zmienić a bez zmiany program błędnie interpretuje plik .dat

Nie bit, tylko bajt, bo to ogromna różnica; I dzieje się tak, dlatego że używasz jakichś cudów, zamiast skorzystać z klasy TFileStream i uzupełnić plik jak należy;

Masz w tej klasie metodę WriteBuffer, której wystarczy podać jako Buffer pierwszy znak łańcucha oraz w drugim parametrze podać ilość zapisywanych znaków:

uses
  Classes;
var
  fsOutput: TFileStream;
  strBuffer: AnsiString = 'example value';
begin
  fsOutput := TFileStream.Create('C:\Binary.dat', fmCreate or fmOpenWrite);
  try
    fsOutput.WriteBuffer(strBuffer[1], Length(strBuffer));
  finally
    fsOutput.Free();
  end;

  Write('done...');
  ReadLn();
end.

W pliku docelowym (C:\Binary.dat) znajdzie się tylko i wyłącznie bufor example value, bez "dziwnego" prefiksu; Ty najpierw wpisz sobie nagłówek (jeśli jest stały to zrób sobie tablicę i ją jako bufor wpisz do pliku), a następnie w ten sposób co wyżej wpisz łańcuch(y);

A najlepiej to by było, gdybyś podał konkretnie z czego ma się plik składać, ile każde pole ma mieć bajtów i jakiego typu dane mają się tam znajdować; Najlepiej w postaci tabelki, żeby nie marnować czasu na czytanie w kółko dziwnych opisów.

2

zamiast Rec.Op := '0' +s2; napisz Rec.Op := #0 +s2; lub Rec.Op := #1 +s2;
a jeszcze lepiej

  TRecord = packed record
   A : Byte;
   B : Byte;
   C : Byte;
   D : Byte;
   E : Byte;
   Znak1: Byte;
   Im : String[22];
   Znak2: Byte;
   Op :  String[5];
   G : Byte;
  end;
0

Jak człowiek półprzytomny po 15h pracy to później pisze bzdury i mało zrozumiale:) Tak chodziło mi o bajt, później dokładnie postaram się opisać co i jak.

0

Dziękuje @abrakadaber Brakowało mi właśnie #0 :)
Obecnie zrobiłem coś takiego:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit3: TEdit;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
 type

  TRecord = packed record

   Im : String[28];
   Op :  String[6];
   G : Byte;
  end;

procedure TForm1.Button1Click(Sender: TObject);

var
  F: file of TRecord;
  Rec : TRecord;
  s, s1, s2               : string;
  i :Integer;

begin

  s:= trim(Edit1.Text);
  s1:= trim(Edit2.Text);
  s2:= trim(Edit3.Text);

   Rec.Im :=  #0 + #0 + #0 + #23 + #0 +s + s1;
   Rec.Op := #1 +s2;
   Rec.G := 70;
   AssignFile(F, 'File.dat');
  try
    Rewrite(F);
    Write(F, Rec);
  finally
    CloseFile(F);
  end;
end;

end.

Jest prawie idealnie bo tworzy mi taki plik:

user image

Muszę tylko zmienić Bajt tworzony przez String z 1C na 21 tylko nie bardzo wiem jak i czy jest taka możliwość.

Dla niektórych są to może banały ale już dawno nie programowałem..

0

zobacz zamiast

   Im : String[28];
   Op :  String[6];

tak

   Im : AnsiString[28];
   Op :  AnsiString[6];
2
type

  TRecord = packed record
   A : Byte;
   B : Byte;
   C : Byte;
   D : Byte;
   E : Byte;
   Im : array [1..23] of char;
   Op : array [1..6] of char;
   G : Byte;
  end;

procedure StrToArr(const s: string; var a: array of char);
var
  i: Integer;
begin
  for i := 1 to Length(a) do
    a[i - 1] := s[i];
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  F: file of TRecord;
  Rec : TRecord;
  s, s1, s2: string;
  i :Integer;
begin
  s:= trim('12345678901234567890123');
  s1:= trim('12345678901234567890123');
  s2:= trim('12345');

   Rec.A := 33;
   Rec.B := 00;
   Rec.C := 00;
   Rec.D := 00;
   Rec.E := 23;
   StrToArr(s1, Rec.Im);
   StrToArr(#0 +s2, Rec.Op);
   Rec.G := 70;
   AssignFile(F, 'd:\download\File.dat');
  try
    Rewrite(F);
    Write(F, Rec);
  finally
    CloseFile(F);
  end;
end;

przy string[23] dodatkowo jest zapisywany bajt rozmiaru i tego się nie da przeskoczyć

0

Bardzo dziękuję za podpowiedzi i pomoc :)

Po lekkiej modyfikacji wszystko działa tak jak chciałem.

Kod końcowy:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Edit3: TEdit;
    Button: TButton;
    procedure ButtonClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
 type

  TRecord = packed record
   A : Byte;
   B : Byte;
   C : Byte;
   D : Byte;
   E : Byte;
   F : Byte;
   Im : array [1..15] of char;
   Ko : array [1..8] of char;
   Op : array [1..7] of char;
   G : Byte;
  end;

procedure StrToArr(const s: string; var a: array of char);
var
  i: Integer;
begin
  for i := 1 to Length(a) do
    a[i - 1] := s[i];
end;

procedure TForm1.ButtonClick(Sender: TObject);
var
  F: file of TRecord;
  Rec : TRecord;
  s, s1, s2: string;
  i :Integer;
begin
  s:= trim(Edit1.Text);
  s1:= trim(Edit2.Text);
  s2:= trim(Edit3.Text);

   Rec.A := 33;
   Rec.B := 00;
   Rec.C := 00;
   Rec.D := 00;
   Rec.E := 23;
   Rec.F := 00;
   StrToArr(s, Rec.Im);
   StrToArr(s1, Rec.Ko);
   StrToArr(#6 + #0 + s2, Rec.Op);
   Rec.G := 70;
 AssignFile(F, 'File.dat');
  try
    Rewrite(F);
    Write(F, Rec);
  finally
    CloseFile(F);
  end;
end;

end.

W załączniku projekt dla potomnych, czas chyba wrócić do programowania i przypomnieć sobie wszystko. Jeszcze raz dziękuję za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0