如何向后读取文件以有效地查找子字符串

2024-01-20

我有一个巨大的这种结构的日志文件:

“时间戳”:{“标识符”:值}

"1463403600":{"AA":74.42},
"1463403601":{"AA":29.55},
"1463403603":{"AA":24.78},
"1463403604":{"AA":8.46},
"1463403605":{"AA":44.84},
"1463403607":{"AA":87.05},
"1463403608":{"AA":54.81},
"1463403609":{"AA":93.1},
"1463403611":{"AA":77.64},
"1463403612":{"AA":33.39},
"1463403613":{"AA":69.2},

我想在给定的时间戳之后提取内容,例如:

std::ifstream * myfunc( uint32_t timestamp) 

例子:

myfunc(1463403611);
/* returns
"1463403611":{"AA":77.64},
"1463403612":{"AA":33.39},
"1463403613":{"AA":69.2},
*/

日志文件很长 - 太长而无法将其保留在内存中。该代码将在资源有限的嵌入式设备(80Mhz,~10kB 可用内存)上运行,因此我正在寻找一些有效解决方案的想法。

日志文件可能有 500k+ 条目,并且 99% 的时间时间戳将位于最后 100 行,因此从文件的开头开始并检查每一行是否有正确的时间戳将非常低效。

所以我想我正在寻找一种解决方案来逐行向后读取文件。 我真的没有一个解决方案如何在不将大块加载到内存的情况下有效地做到这一点。

我尝试从 EOF 开始读取 200 字节的块,但遇到了这样的问题:在许多情况下,该块将时间戳减半。我试图检测到这一点,并在需要时重新选择一些字节,但我感​​觉,必须有一个聪明的解决方案。


嗯,我发现这很有趣,所以我为它做了一个概念验证二分查找 https://en.wikipedia.org/wiki/Binary_search_algorithm idea.

这没有经过充分的测试,可能还有一些问题,但到目前为止似乎有效,并且演示了分而治之的思想。您检查文件的中间,然后根据是否太高或太低,将数据分成两部分并搜索相关的一半。您递归地执行此操作,直到足够接近为止。

#include <ctime>
#include <cmath>
#include <cstdlib>
#include <string>
#include <fstream>
#include <iostream>

// Don't use this, its just to show how many reads
// are being done to find the record.
int global_counter;

std::streampos find_stamp(std::istream& is, long stamp, std::streampos pos, std::streampos end)
{
    ++global_counter;

    if(pos == 0) // can't divide zero
        return 0;

    std::string s;
    long found_stamp;

    // extract nearest timestamp after pos
    is.seekg(pos);
    if(!(std::getline(std::getline(is, s, ','), s, '"') >> found_stamp))
        return end;

    // if its too big check first half of this region
    if(found_stamp > stamp)
        return find_stamp(is, stamp, pos / 2, pos);

    // if its not within 10 timestamp seconds check end half of this region
    if(stamp - found_stamp > 10)
        return find_stamp(is, stamp, (pos + end) / 2, end);

    // read record by record (prolly more efficient than skipping)
    pos = is.tellg();
    while(std::getline(std::getline(is, s, ','), s, '"') >> found_stamp)
    {
        if(found_stamp > stamp)
            return pos;
        pos = is.tellg();
    }
    return end;
}

void print_after(const std::string& filename, long stamp)
{
    // open at end of file (to get length)
    std::ifstream ifs(filename, std::ios::ate);

    std::streampos end = ifs.tellg();
    auto pos = end / 2; // start checking in middle

    // find position before required record
    // (may be in the middle of a record)
    if((pos = find_stamp(ifs, stamp, pos, end)) != end)
    {
        ifs.seekg(pos);

        std::string line;
        std::getline(ifs, line, ','); // skip to next whole record

        // print out all following recors
        while(std::getline(ifs, line, ','))
            std::cout << line;
    }
}

inline
std::string leading_zeros(int n, int zeros = 2)
{
    std::string s;
    for(int z = std::pow(10, zeros - 1); z; z /= 10)
        s += (n < z ? "0":"");
    return s + std::to_string(n);
}

int main()
{
    std::srand(std::time(0));

    // generate some test data
    std::ofstream ofs("test.txt");

    for(int i = 0; i < 1000; ++i)
    {
        ofs << '"' << leading_zeros(i, 10) << '"';
        ofs << ":{\"AA\":" << (std::rand() % 100);
        ofs << '.' << (std::rand() % 100) << "},\n";
    }

    ofs.close();

    global_counter = 0;
    print_after("test.txt", 993);

    std::cout << "find checked " << global_counter << " places in the file\n";
}

Output:

"0000000994":{"AA":80.6}
"0000000995":{"AA":11.90}
"0000000996":{"AA":16.43}
"0000000997":{"AA":53.11}
"0000000998":{"AA":68.43}
"0000000999":{"AA":79.77}
find checked 6 places in the file
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何向后读取文件以有效地查找子字符串 的相关文章

  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 在Python中获取文件描述符的位置

    比如说 我有一个原始数字文件描述符 我需要根据它获取文件中的当前位置 import os psutil some code that works with file lp lib open path to file p psutil Pro
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 关于 C++ 转换:参数 1 从“[some_class]”到“[some_class]&”没有已知的转换

    我正在研究 C 并且遇到了一个错误 我不知道确切的原因 我已经找到了解决方案 但仍然想知道原因 class Base public void something Base b int main Base b b something Base
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 将控制台重定向到 .NET 程序中的字符串

    如何重定向写入控制台的任何内容以写入字符串 对于您自己的流程 Console SetOut http msdn microsoft com en us library system console setout aspx并将其重定向到构建在
  • 测试用例执行完成后,无论是否通过,如何将测试用例结果保存在变量中?

    我正在使用 NUNIT 在 Visual Studio 中使用 Selenium WebDriver 测试用例的代码是 我想在执行测试用例后立即在变量中记录测试用例通过或失败的情况 我怎样才能实现这一点 NUnit 假设您使用 NUnit
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • 如何将服务器服务连接到 Dynamics Online

    我正在修改内部管理应用程序以连接到我们的在线托管 Dynamics 2016 实例 根据一些在线教程 我一直在使用OrganizationServiceProxy out of Microsoft Xrm Sdk Client来自 SDK
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • 为什么当shared_ptr调用派生和基析构函数时,unique_ptr只调用基析构函数? [复制]

    这个问题在这里已经有答案了 为什么以下代码的输出会根据我是否使用shared ptr or unique ptr 的输出shared ptr这是有道理的 因为该对象已完全被破坏 而在unique ptr 只有基类部分被破坏 我以为当我使用智
  • Android:通过视频动态模糊表面

    我正在构建一个 Android 应用程序 其中 ExoPlayer 在 SurfaceView 的表面上播放视频 并且我正在研究是否可以动态模糊播放的视频 涉及首先生成要模糊的视图位图的模糊技术将不起作用 因为 SurfaceView 的表
  • WIX 安装程序未正确显示 WixUI 对话框的自定义图像

    In my WIX我正在使用自定义安装程序WixUIDialogBmp安装人员的图像Welcome and Completion页 但如下图所示 图像无法正确显示 我正在尝试遵循这个官方文档 http wixtoolset org docu
  • 解决这个分配珠子难题的算法?

    假设你有一个圆圈 如下所示 N点 并且你有N珠子分布在槽中 Here s an example 每个珠子都可以顺时针移动X插槽 这需要花费X 2美元 您的目标是最终在每个槽中获得一颗珠子 完成这项任务至少需要花多少钱 这个问题更有趣的变体
  • 加载后获取 Highcharts 系列数据

    我试图在调用 Highcharts 图表并将其加载到页面后获取系列数据 到目前为止 我只成功地获得了一堆字符串 这显然不是我想要的 不知道是否有人可以帮助我解决这个问题 jQuery 代码 success function chartDat
  • Spring AOP 创建额外的 bean

    我正在玩Spring AOP 这是一个简单的类 public class CModel extends Car private double torqueMeasure 1 public CModel System out println
  • 如何使用 kubernetes python 客户端排空节点?

    我正在尝试使用官方的 kubernetes 工作节点自动化kubernetes python 客户端 https github com kubernetes incubator client python 我目前正在寻找一种方法安全地将所有
  • Jena Fuseki 服务器命令未找到

    我是 Jena Fuseki 服务器的新手 根据链接http jena apache org documentation serving data index html http jena apache org documentation
  • 如何在 jenkins 上使用 ant 从 .product 构建 eclipse rcp 应用程序

    我想构建一个 Eclipse RCP 应用程序 我有一个产品配置文件和一个带有许多第三方插件的目标平台 从 Eclipse IDE 的导出工作完美无缺 但这很难说是专业的 所以我也想让它在詹金斯上工作 构建服务器从 SVN 获取文件 没有
  • matlab/octave - 广义矩阵乘法

    我想做一个函数来概括矩阵乘法 基本上 它应该能够执行标准矩阵乘法 但它应该允许通过任何其他函数更改两个二元运算符的乘积 和 目标是在 CPU 和内存方面尽可能高效 当然 它的效率总是低于 A B 但操作员的灵活性是这里的重点 这是我阅读后可
  • `this.some_property` 在匿名回调函数中变为未定义

    所以我不太明白为什么这个变量这个任务在我的目标对象内部的添加事件侦听器中变得未定义 我有一种感觉 它可能与异步编程有关 我仍然不完全理解 抱歉 我有点 JS 菜鸟 但是如果你们能向我解释我做错了什么以及什么可能是更好的解决方案 那就太棒了
  • 使用 Azure AD 多租户进行 Azure AD B2C 身份验证

    我已按照本文配置了 Azure AD 多租户身份验证 https learn microsoft com en us azure active directory b2c identity provider azure ad multi t
  • 如何刷新 iframe url?

    我正在使用 ionic 创建一个应用程序 其中使用 iframe 显示 URL 这是 HTML 代码 这是角度js scope iframeHeight window innerHeight document getElementById
  • 自适应卡 - 以字节为单位提供图像

    我正在尝试将图像放入 Bot 框架中的自适应卡中 如下所示 card Body Add new AdaptiveImage Type Image Url new Uri pictureUrl Size AdaptiveImageSize L
  • jQuery .val() 在更改选择框时返回未定义

    我有一个带有一些日期的选择框 我想在输入更改时获取所述日期的值 我的价值总是变得不确定 date pick change function var values date pick selected val alert values Fid
  • 在 C# 中直接在 DateTimePicker 上转到月份和年份

    如果用户在我的中输入日期 我该如何实现这一点DateTimePicker它会自动聚焦月份部分 输入该月份部分后 会转到年份部分 因为我不希望他必须按右键才能聚焦 有没有办法以编程方式执行此操作 用户不可能已经单击月份或年份部分 因为他使用键
  • 构建管道的默认分支。这是什么意思?

    在 Azure DevOps Services 的发布工作流程中 在设置持续部署触发器时 有一个选项 构建管道的默认分支 我不明白这意味着什么以及如何查看项目中不同管道的默认分支 任何有关这方面的文档的参考也会有所帮助 这也出现在管道中的其
  • 如何将 DataFrame 的列名从字符串转换为整数

    在下面的代码中 我将一个字符串读入 DataFrame 但即使输入字符串的标头是数字 它们也会作为字符串读入 1 2 有没有办法将它们作为数字读取 或者随后将它们转换为数字 import pandas as pd from StringIO
  • java初学者:如何在哈希图中对键进行排序?

    我是java新手 正在学习哈希图的概念 我很困惑哈希图中的键是如何排序的 我知道它基于字符串长度 但我很困惑当字符串长度相同时数据如何排序 import java util HashMap import java util Iterator
  • 如何向后读取文件以有效地查找子字符串

    我有一个巨大的这种结构的日志文件 时间戳 标识符 值 1463403600 AA 74 42 1463403601 AA 29 55 1463403603 AA 24 78 1463403604 AA 8 46 1463403605 AA