Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Использование TFileStream для текста и бинарного файла [D7, XP]


mnj ©   (2011-12-06 01:29:00) 

Товарищи, есть задача: нужно читать разные варианты грида из программы Surfer: текстовый и два варианта бинарных.


mnj   (2011-12-07 13:45:00) [1]

спасибо всем - не ожидал дискуссии. уже все сделал


han_malign   (2011-12-06 17:38:00) [2]

with( PDSFileContent(dump.Memory) ^)do


han_malign   (2011-12-06 17:37:00) [3]


> > Так тоже неплохо

- при некоторых условиях
type
   PDSFileContent = ^TDSFileContent;
   TDSFileContent = record
       case DSType: LongWord of
       $41415344: (text: array[0..max_size-1]of AnsiChar);
       $42425344: (bb: array[0..max_size div sizeof(TDSBBRecord)-1]of TDSBBREcord);
       $42525344: (rb: array[0..max_size div sizeof(TDSRBRecord)-1]of TDSRBREcord);
   end;
var dump: TMemoryStream;
    slDump: TStringList;
    nRecords, i: integer;
begin
   dump:= TMemoryStream.Create;
   try
   dump.LoadFromFile(DSFileName);
   with(PDSFileContent(dump.Memory))do
   if( dump.size > sizeof(DSType) )then begin
        case(DSType)of
        $41415344: begin
             slDump:= TStringList.Create;
             try
             dump.Position:= sizeof(DSType);
             slDump.LoadFromStream(dump);
             ...
             finally
                slDump.Free;
             end;
        end{DSAA};
        $42425344: begin
             nRecords:= (dump.Size - sizeof(DSType)) div sizeof(bb[0]);
             for i:= 0 to nRecords-1 do
                with(bb[i])do begin
                     ...
                end;
        end{DSBB};
        $42525344: begin
             nRecords:= (dump.Size - sizeof(DSType)) div sizeof(rb[0]);
             for i:= 0 to nRecords-1 do
                with(rb[i])do begin
                     ...
                end;
        end{DSRB};
        end{case(DSType)};
   end;
   fynally
      dump.Free;
   end;
end;

- max_size - влияет только на то - сколько элементов отладчик покажет...


Ega23   (2011-12-06 16:19:00) [4]


> Так тоже неплохо


const
ID1 : Cardinal = $ABCDEF01;
ID2 : Cardinal = $ABCDEF02;
ID3 : Cardinal = $ABCDEF03;
.....

var
 aHeader: Cardinal;
begin
 stream.ReadBuffer(aHeader, SizeOf(Cardinal));
 case aHeader of
   ID1: ....;
   ID2: ....;
   ID3: ....;
   .....
 end;
end;


И не надо заморачиваться с Ansi это или юникод, чар или не чар.


mnj   (2011-12-06 14:44:00) [5]

Так тоже неплохо. Это одноразовая операция
var InFile: TFileStream;
B: byte;
I: integer;

.....
 for I:= 1 to 4 do
    begin
      InFile.Read(B,1);    //чтение сигнатуры, определяющей вид грида
      Id:= Id + char(B);
    end;
  if Id = 'DSAA' then....


Плохиш   (2011-12-06 12:35:00) [6]


> mnj   (06.12.11 11:56) [5]

Типа программистом любая домохозяйка стать может. работа не пыльная и думать не надо, сиди дави кнопки и греби бабло.

 header = '1234';
 Stream.ReadBuffer(header[1] , 4); // вот теперь прочитали первые четыре байта и интерпретировали их так как надо.


Сергей М.   (2011-12-06 12:07:00) [7]

> DSAA, DSBB, DSRB

Сделай соответствующие даблворды из кодов этого хозяйства и читай из стрима не в string[4], а в даблворд и сравнивай с подготовленными даблвордами сигнатур


Сергей М.   (2011-12-06 12:04:00) [8]


> Почему улетает первый символ?


Потому что первый символ при выводе трактуется счетчик символов в строке


mnj   (2011-12-06 11:56:00) [9]

В том и фокус, что Read и ReadBuffer не дают полностью четыре символа сигнатуры - первый пропадает, вместо DSAA получаю SAA. Если побайтно читать и склеивать в строку, тогда получается правильно. Почему улетает первый символ?


KilkennyCat   (2011-12-06 01:58:00) [10]

да, еще незабыть Stream.Free; выполнить, когда он ненужен будет.


KilkennyCat   (2011-12-06 01:56:00) [11]

ну что-то типа:
var
 b : byte;
 s : string;
 header : string[4];
try
 Stream := TFileStream.Create('c:\test.dat', fmOpenRead);
 StreamLength := Stream.Size;
 Stream.ReadBuffer(header , sizeof(header)); // прочитали первые четыре байта
 while Stream.Pos < Stream.Size do bedin  // бежим, пока файл не кончится
   Stream.ReadBuffer(b, sizeof(b));
   if b = признак конца строки then begin
     (тут получили строку s, делаем с ней что нужно);
     s := '';
   end else s := s + chr(b);
 end;
except
    //обработка ошибки открытия файла
end;


mnj   (2011-12-06 01:38:00) [12]

Виноват, случайно отправил. Так вот: первые 4 байта есть заголовок для каждого типа (DSAA, DSBB, DSRB). Если я организую это через FileStream, как мне читать текстовый файл, если он представляет собой набор строк разной длины, заранее неизвестной (бинарные имеют строгий формат). Могу привести описание форматов при необходимости. Спасибо.


KilkennyCat   (2011-12-06 01:37:00) [13]

ну так читай. TFileStream форматонезависим.


Наверх

Титульная страница Поиск, карта сайта Написать письмо