TDictionary 保存到文件

2024-03-11

我有很多文件(大约 160 000 个),我需要有关文件中各个单词的位置的信息(全文)。所以我这样使用字典:

WordDict : TDictionary<string, TDictionary<string, TIntegerDynArray>>;

现在我知道 WORD1 位于 FILE1、FILE3 和 FILE100 中,并且位于每个文件 , 等中。 我可以填满它,我可以使用它——速度非常快。但我不知道如何有效地将字典存储到文件中。

编辑:有效 - 我的意思是文件快速且小


您可以使用Delphi的流系统来编写专有的流格式。如果大小很重要(与速度相反),您可以压缩流。这是一些代码:

type
  TFilePos = TArray<Integer>;
  TFileDict = TDictionary<string, TFilePos>;
  TWordDict = class (TDictionary<string, TFileDict>)
  private
    procedure LoadFromStream(stream: TStream);
    procedure SaveToStream(stream: TStream);
  public
    procedure LoadFromZip(const AFileName: string);
    procedure LoadFromFile(const AFileName: string);
    procedure SaveToZip(const AFileName: string);
    procedure SaveToFile(const AFileName: string);
  end;

procedure TWordDict.LoadFromZip(const AFileName: string);
var
  stream: TStream;
  localHeader: TZipHeader;
  zipFile: TZipFile;
begin
  zipFile := TZipFile.Create;
  try
    zipFIle.Open(AFIleName, zmRead);
    zipFile.Read('worddict', stream, localHeader);
    try
      LoadFromStream(stream);
    finally
      stream.Free;
    end;
    zipFile.Close;
  finally
    zipFile.Free;
  end;
end;

procedure TWordDict.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, 'worddict');
      zipFile.Close;
    finally
      zipFile.Free;
    end;
  finally
    stream.Free;
  end;
end;

procedure TWordDict.SaveToStream(stream: TStream);
var
  posi: System.Generics.Collections.TPair<string, TFilePos>;
  i: Integer;
  pair: System.Generics.Collections.TPair<string, TFileDict>;
  writer: TWriter;
begin
  writer := TWriter.Create(stream, 4096);
  try
    writer.WriteListBegin;
    for pair in Self do
    begin
      writer.WriteString(pair.Key);
      writer.WriteListBegin;
      for posi in pair.Value do
      begin
        writer.WriteString(posi.Key);
        writer.WriteInteger(Length(posi.Value));
        for i in posi.Value do
        begin
          writer.WriteInteger(i);
        end;
      end;
      writer.WriteListEnd;
    end;
    writer.WriteListEnd;
  finally
    writer.Free;
  end;
end;

procedure TWordDict.LoadFromStream(stream: TStream);
var
  sFiles: TFileDict;
  aPosi: TFilePos;
  size: Integer;
  i: Integer;
  sWord: string;
  reader: TReader;
  sFile: string;
begin
  Clear;
  reader := TReader.Create(stream, 1024);
  try
    reader.ReadListBegin;
    while not reader.EndOfList do
    begin
      sWord := reader.ReadString;
      sFiles := TFileDict.Create;
      reader.ReadListBegin;
      while not reader.EndOfList do
      begin
        sFile := reader.ReadString;
        size := reader.ReadInteger;
        SetLength(aPosi, size);
        for I := 0 to size - 1 do
        begin
          aPosi[I] := reader.ReadInteger;
        end;
        sFiles.Add(sFile, Copy(aPosi));
      end;
      reader.ReadListEnd;
      Add(sWord, sFiles);
    end;
    reader.ReadListEnd;
  finally
    reader.Free;
  end;
end;

procedure TWordDict.LoadFromFile(const AFileName: string);
var
  stream: TStream;
begin
  stream := TFileStream.Create(AFileName, fmOpenRead);
  try
    LoadFromStream(stream);
  finally
    stream.Free;
  end;
end;

procedure TWordDict.SaveToFile(const AFileName: string);
var
  stream: TStream;
begin
  stream := TFileStream.Create(AFileName, fmCreate);
  try
    SaveToStream(stream);
  finally
    stream.Free;
  end;
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TDictionary 保存到文件 的相关文章

随机推荐

  • 在 Racket 源代码中选择学生语言

    我正在尝试为 DrRacket 编写一个源文件 指定其中一种语言如何设计教学语言的程序 see 球拍文档 http docs racket lang org drracket htdp langs html 我知道我可以在 DrRacket
  • Android 上符合 OpenGL-ES 2.0 所需的最小纹理大小?

    某个硬件是否需要支持最小纹理尺寸才能符合 OpenGL ES 2 0 规范 GL MAX TEXTURE SIZE 值必须至少为 1024 或 2048 或类似的值 我想知道这一点的原因是因为我正在研究使用着色器的东西 因此必须是 Open
  • 通过 Selenium Grid 运行 Selenium IDE 测试

    首先我应该说 我感到遗憾和痛苦noob 但我正在努力改变这一点 我不懂任何编程语言 但通过做足够的研究来完成我需要完成的任何工作 从而成功地 让事情发生 不管怎样 我一直在使用 Selenium IDE 创建 Selenium 测试 但在通
  • MySQL PHPMyAdmin 错误 #1062 - 键“PRIMARY”重复条目“0”

    现在我想添加一个主键id列 但它抛出错误 1062 密钥 PRIMARY 重复输入 0 我已经尝试过这个 向现有表添加主键 https stackoverflow com questions 11794659 add primary key
  • 选择用于实现分布式消息传递算法的编程语言

    基本上 我想实现以下算法并分析使用这些算法构建的系统在不同条件下的行为 八卦协议 多个paxos 一致的散列 我的兴趣在于这些算法 我基本上是在寻找一种编程语言 可以让我快速编写这些算法并深入理解这些算法 我应该选择哪种语言 Java Sc
  • 如何签署由第 3 方提供的发布 iphone 二进制文件?

    我收到了一家外包公司为我工作的公司开发的 iPhone 应用程序 我无权访问源代码 只能访问已编译的二进制文件 我希望能够使用我们的证书 配置信息等对其进行签名 以便我可以将其提交到应用程序商店 我该怎么做呢 我知道的存在codesign但
  • 如何切换到“更多”视图中的选项卡栏项目?

    我正在用 Objective C 为 Iphone Ipad 编写一个应用程序 我在标签栏的 更多 中有一些项目 我想切换到其中一种视图 我该怎么做 通常我会使用 selectedIndex 但它在 更多 选项卡上不起作用 要从更多屏幕选择
  • 使用 for 迭代 python 列表时如何指定类型/类名

    我知道 python 是动态类型语言 但想知道这是否可能 假设我有一个名为 people 的类 Person 的列表 people people append Person james for p in people p name p na
  • PHP(或其他):处理“不可能发生”的异常的策略

    考虑以下代码 class C throws InvalidArgumentException function classCreateInstance class if is string class throw new InvalidAr
  • mysql查询中的正则表达式

    我有 mysql 表值 例如 1 2 1 2 3 1 4 5 1 4 5 12 15 15 45 75 1 5 15 25 35 55 55 65 75 我想选择哪些行的编号为 5 而不是 15 25 或 35 我尝试过使用 LIKE 查询
  • 材质按钮 切换组单选

    我怎样才能强制材质按钮切换组表现得像 RadioGroup 一样 总是至少有一个选定的项目 环境setSingleSelection true 如果您单击组中的按钮两次 还可以增加不选择任何内容的可能性 这是我的代码
  • 暂时禁用 Lollipop CheckBox 上的动画

    我有一个 ListView 其中包含复选框的行 此 ListView 附加了过滤行为 它通过设置新数据来回收这些行 通过一个简单的setData 方法 随着过滤条件的变化 发生这种情况时 任何具有以下属性的回收行checked状态更改将更新
  • Hibernate 4 和 joda-time

    他们婚姻幸福吗 我使用的是最新版本的 hibernate 4 和 1 3 版本joda 时间休眠支持 http www joda org joda time hibernate 我也认为这是当前的最新版本 使用注释时 一切似乎都工作正常 按
  • 使用 Rspec 测试“创建后”

    我正在尝试使用 Rspec 测试 创建后 操作 代码如下 def valid attributes zone gt Flymgr Zone new countries gt Flymgr ZoneCountry first name gt
  • 无需正则表达式即可简单搜索和替换

    我有一个包含各种通配符的文件 我希望能够从 Bash shell 脚本中替换它 我有以下内容 该内容非常有效 直到其中一个变量包含正则表达式特有的字符 VERSION 1 0 perl i pe s VERSION VERSION g tx
  • 经典asp中的vbscript语法

    我有一个 vbscript 我想在其中运行一种asp 我在运行脚本时遇到问题 所以我想我需要一些帮助来确保 asp 知道它是 vvbscript 或其他东西 最后一个脚本是我运行时遇到问题的脚本 这是我所拥有的
  • 当以字符串形式给出方法名称时,如何调用 Java 方法?

    如果我有两个变量 Object obj String methodName getName 在不知道班级的情况下obj 我怎样才能调用由methodName on it 被调用的方法没有参数 并且有一个String返回值 它是Java be
  • 基于整数而不是字符串按升序对数组进行排序

    我有一个具有以下结构的数组 myArray
  • 如何使用 Koala gem 获取 Facebook 用户的照片?

    我正在尝试使用以下方法获取 Facebook 用户朋友的照片 他们的 facebook id 但使用以下代码返回 nil 图片网址 我使用的代码如下 picture url user get picture 1000000111 其中 us
  • TDictionary 保存到文件

    我有很多文件 大约 160 000 个 我需要有关文件中各个单词的位置的信息 全文 所以我这样使用字典 WordDict TDictionary