Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Можно ли данные в дереве TDictionary писать в файл, как массив?

#delphi #generics


Вопрос, непосредственно связанный с моим предыдущим Импорт данных секвенирования
и обработка SAM-файлов в TDictionary

Ранее, когда мы держали данные для обработки в массиве записей, мы просто создавали
типовой файл и сбрасывали данные (а затем архивировали в ZIP, хорошо сжималось):

type
  data = record
   <...>
   end;
var
  f: file of data;
  d: array of data;


Теперь, если мы будем использовать структуру 

type
DataType = record
  name,qual, info, seq:string;
  data:array[1..30] of double;
  paired, structured:boolean;
  ref:integer;
end;

TData3 = TDictionary;  
TData1 = class(TDictionary);
   end;


Можно ли использовать тот же подход, что и раньше, т.е. сбрасывать данные в типовой
файл? Или необходимо использовать FileStream?
    


Ответы

Ответ 1



Можно конвертировать в массив, но, подозреваю, что не нужно. Особенно, если вы планируете делать это лишь для записи. Гораздо проще работать с потоками. Могу привести пример, как это реализовано у нас в базовом классе: TVCFFile = class (TDictionary) // private <...> procedure SaveToStream(stream: TStream); protected <...> public <...> procedure SaveToZip(const AFileName: string); override; procedure SaveToFile(const AFileName: string); override; end; procedure TVCFFile.SaveToStream(stream: TStream); var posi: System.Generics.Collections.TPair; pair:System.Generics.Collections.TPair; third:System.Generics.Collections.TPair; i: Integer; writer: TWriter; begin writer := TWriter.Create(stream, 4096); try writer.WriteListBegin; for third in Self do begin writer.WriteString(third.Key); writer.WriteListBegin; for pair in third.Value do begin writer.WriteInteger(pair.Key); writer.WriteListBegin; for posi in pair.Value do begin writer.WriteString(posi.Key); writer.WriteDouble(posi.Value.qual); writer.WriteString(posi.Value.alt); writer.WriteString(posi.Value.filter); writer.WriteString(posi.Value.info); end; writer.WriteListEnd; end; writer.WriteListEnd; end; writer.WriteListEnd; finally writer.Free; end; end; procedure TVCFFile.SaveToZip(const AFileName: string); var stream: TStream; zipFile: TZipFile; begin stream := TMemoryStream.Create; try SaveToStream(stream); stream.Position := 0; zipFile := TZipFile.Create; try zipFile.Open(AFileName, zmWrite); zipFile.Add(stream, 'bigdata.tvb'); zipFile.Close; finally zipFile.Free; end; finally stream.Free; end; end; procedure TVCFFile.SaveToFile(const AFileName: string); var stream: TStream; begin stream := TFileStream.Create(AFileName, fmCreate); try SaveToStream(stream); finally stream.Free; end; end; Можно просто записать в файл, можно сразу в ZIP-файл, скорость записи и считывания достаточно велика (для загрузки есть аналогичные методы, строите их от обратного). Плюс, понадобятся методы для загрузки из SAM, записи в него же, возможно, понадобится поддержка BED, VCF и прочее, а, может, вы всё это сделаете в других классах.

Комментариев нет:

Отправить комментарий