Page 1 of 1

Запись структуры в файл

Posted: 31.03.2012 18:23
by yuras

Code: Select all

Program tst;
type  bmFileHeader = record	
    Typf : word;        
    Size : longint;     
    Res1 : word;       
    Res2 : word;       
    OfBm : longint;  
  end;
var
data:bmFileHeader ;
File:TFileStream;
begin
data.Typf:=16973;
data.size:=1024;
data.Res1:=0;
data.Res2:=0;
data.OfBm:=62;
file := TFileStream.Create('D:\test',fmcreate);
file.seek(0,soFromEnd);
file.writebuffer(data,Length(data)); 
file.Free;
end;
вот пример, при компиляции выдает ошибку, 'type mismatch' на writebuffer. как правильно записать record в файл? Ну и прочитать оттуда тоже)

Re: Запись структуры в файл

Posted: 31.03.2012 20:17
by Vizit0r
sizeof всю жизнь было, а не Length
хотя, честно говоря, не проверял в ПС ни разу.

Re: Запись структуры в файл

Posted: 31.03.2012 21:13
by yuras
Vizit0r wrote:sizeof всю жизнь было, а не Length
хотя, честно говоря, не проверял в ПС ни разу.
с sizeof тоже самое. если стринговую переменную ставить, компиляция проходит.

Re: Запись структуры в файл

Posted: 31.03.2012 22:50
by Vizit0r
потому что правильно

Code: Select all

file.writebuffer(data,sizeof(bmFileHeader));
Потому что тебе надо записать размер записи, а не переменной.
размер переменной в данном случае равен 4, ибо указатель на запись. но ПС в такие тонкости не вникает, и дает ошибку. оно и к лучшему.

Re: Запись структуры в файл

Posted: 01.04.2012 0:25
by yuras
Vizit0r wrote:потому что правильно

Code: Select all

file.writebuffer(data,sizeof(bmFileHeader));
Потому что тебе надо записать размер записи, а не переменной.
размер переменной в данном случае равен 4, ибо указатель на запись. но ПС в такие тонкости не вникает, и дает ошибку. оно и к лучшему.
Да, логично, но все равно та-же ошибка.
(tst.sc at 1214:44): Type mismatch

Re: Запись структуры в файл

Posted: 01.04.2012 8:44
by Vizit0r
а, пардон. я вчера проверил, вроде откомпилировалось нормально.
сутра проверил - глюк :)

Re: Запись структуры в файл

Posted: 01.04.2012 9:26
by Vizit0r
изменено, причина: проблема в том, что первым параметром должен быть String, а не в sizeof.

Re: Запись структуры в файл

Posted: 08.07.2013 8:04
by VeL
Структуру нельзя никак записать в файл?

Re: Запись структуры в файл

Posted: 08.07.2013 12:11
by Vizit0r
вот пример с сохранением структур из дельфийского исходника стелса.

Code: Select all

type TShard_v_5 = record     
    ShardName : String[50];
    IP : String[49];
    Port : Cardinal;
    UseProxy : Boolean;
    ProxyIP : String[15];
    ProxyPort : Word;
    ProxyAuthMethod : Byte;
    ProxyAuthLogin : String[48];
    TooltipDelay : Word;
    ProxyAuthPass : String[48];
    EnableRazorSupport : Boolean;
    ProxyType : Byte;
    EncryptionEnabled : Boolean;
    Ver : TClientVer;
    UOMULPath : String[255];
    SelClient : Byte;
    NulTargets : boolean;
  end; 

PShard_v_5 = ^TShard_v_5;

var   filehwnd : HWND;
ShardData : TShard_v_5;
WriteBytes, wb : Cardinal;
  WriteResult : Boolean;


  filehwnd  := CreateFile(pChar(ShardsPath), GENERIC_WRITE, 0, Nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  if (filehwnd = INVALID_HANDLE_VALUE) then
  begin
    AddToLog("System", MSG_GLOBALSETUP_ERROR, "Error with opening: INVALID HANDLE VALUE");
    Exit;
  end;
  //Если файл открыли нормально, то начинаем записывать
      ShardData := PShard_v_5 (ShardsList.Items[i])^;
      //Далее сама запись
      while (WriteBytes < BlockSize) do
      begin
        WriteResult := WriteFile(filehwnd, ShardData^, BlockSize, wb, Nil);
        if not WriteResult then
        begin
          MessageBox(Application.Handle, 'Error with saving shards. WriteResult = False.', 'Save shards error', MB_OK);
          CloseHandle(filehwnd);
          Exit;
        end;
        if (wb = 0) then
        begin
          MessageBox(Application.Handle, 'Error with saving shards. WB = 0.', 'Save shards error', MB_OK);
          CloseHandle(filehwnd);
          Exit;
        end;
        WriteBytes := WriteBytes + wb;
      end;

  CloseHandle(filehwnd);
и это отличный пример того, как делать не надо.


Надо как-то так (переписал 10 минут назад код):

Code: Select all

  procedure SaveShardsList(savefilename : string = 'shards.dat');
var i : Integer;
  ShardData : TShard_v_5;
  ShardsPath : String;
  filestr : TFileStream;
  WriteResult : Boolean;
  ShardsVersion : Cardinal;
  mode : Word;
begin
  if ShardsList.Count = 0 then Exit;
  ShardsPath := StealthPath + savefilename;
  if FileExists( savefilename) then
    mode := fmOpenReadWrite or fmShareDenyWrite
  else
    mode := fmCreate;
  try
    filestr := TFileStream.Create(savefilename,mode);
  except
    Exit;
  end;
  //Если файл открыли нормально, то начинаем записывать
  //Сначала запишем версию сохраняемых данных
  ShardsVersion := 5;
  if filestr.Write(ShardsVersion,4) <> 4 then
  begin
    MessageBox(Application.Handle, 'Error with saving shards. ShardsVersion not written', 'Save shards error', MB_OK);
    filestr.Free;
    Exit;
  end;


  if (ShardsList.Count > 0) then
  for i := 0 to ShardsList.Count - 1 do
  begin
    ShardData := PShard_v_5 (ShardsList.Items[i])^;
    //Далее сама запись
    WriteResult := filestr.Write(ShardData,SizeOf(TShard_v_5)) = SizeOf(TShard_v_5);
    if not WriteResult then
    begin
      MessageBox(Application.Handle, 'Error with saving shards. WriteResult = False.', 'Save shards error', MB_OK);
      filestr.Free;
      Exit;
    end;
  end;
  filestr.Free;
end;
понятия не имею, как оно будет вести себя на ПС, но на 6м стелсе, где вместо ПС встроен PAX - точно будет работать.