海量文本数据分割算法

2024-01-11

我有一个动态填充的文本区域(具体来说,我在 Qt 中有一个 QPlainTextEdit,但对于算法建议并不重要)。

现在的问题是有时会出现大量数据,随着更多数据进入我的应用程序,我的应用程序会变得很重,因为所有文本数据都在主内存中。

所以我想到了以下几点。我们可以使用一个文件来存储所有文本数据并动态仅显示有限数量的数据,但同时我必须通过创建在新行时触发的滚动事件来让用户误以为数据大小是文件的大小来了。

有没有针对此类问题的标准算法?


子类QAbstractListModel在那里实现缓存。 读取单元格值时,您将从缓存中获取数据,如果缓存中不存在该值,则更新它。

Tweak QTableView,通过改变委托来实现所需的单元格可视化。注意你必须使用QTableView因为其他QAbstractItemView有破损物品回收,并且不能很好地处理非常大的模型(QTableView不存在这样的问题)。

有一段时间,我编写了大文件的十六进制查看器,并用文件大小 2GB 进行了测试,它运行得很好。

好的,我找到了我的旧代码,这可能是一个很好的例子:

#include <QAbstractTableModel>

class LargeFileCache;

class LageFileDataModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    explicit LageFileDataModel(QObject *parent);

    // QAbstractTableModel
    int rowCount(const QModelIndex &parent) const;
    int columnCount(const QModelIndex &parent) const;
    QVariant data(const QModelIndex &index, int role) const;

signals:

public slots:
    void setFileName(const QString &fileName);

private:
    LargeFileCache *cachedData;
};

// ----- cpp file -----
#include "lagefiledatamodel.h"
#include "largefilecache.h"
#include <QSize>

static const int kBytesPerRow = 16;

LageFileDataModel::LageFileDataModel(QObject *parent)
    : QAbstractTableModel(parent)
{
    cachedData = new LargeFileCache(this);
}

int LageFileDataModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return (cachedData->FileSize() + kBytesPerRow - 1)/kBytesPerRow;
}

int LageFileDataModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return kBytesPerRow;
}

QVariant LageFileDataModel::data(const QModelIndex &index, int role) const
{
    if (index.parent().isValid())
        return QVariant();
    if (index.isValid()) {
        if (role == Qt::DisplayRole) {
            qint64 pos = index.row()*kBytesPerRow + index.column();
            if (pos>=cachedData->FileSize())
                return QString();
            return QString("%1").arg((unsigned char)cachedData->geByte(pos), 2, 0x10, QChar('0'));
        } else if (role == Qt::SizeHintRole) {
            return QSize(30, 30);
        }
    }

    return QVariant();
}

void LageFileDataModel::setFileName(const QString &fileName)
{
    beginResetModel();
    cachedData->SetFileName(fileName);
    endResetModel();
}

这是一个缓存实现:

class LargeFileCache : public QObject
{
    Q_OBJECT
public:
    explicit LargeFileCache(QObject *parent = 0);

    char geByte(qint64 pos);
    qint64 FileSize() const;

signals:

public slots:
    void SetFileName(const QString& filename);

private:
    static const int kPageSize;

    struct Page {
        qint64 offset;
        QByteArray data;
    };

private:
    int maxPageCount;
    qint64 fileSize;

    QFile file;
    QQueue<Page> pages;
};

// ----- cpp file -----
#include "largefilecache.h"

const int LargeFileCache::kPageSize = 1024*4;

LargeFileCache::LargeFileCache(QObject *parent)
    : QObject(parent)
    , maxPageCount(1024)
    , fileSize(0)
{

}

char LargeFileCache::geByte(qint64 pos)
{
    // largefilecache
    if (pos>=fileSize)
        return 0;

    for (int i=0, n=pages.size(); i<n; ++i) {
        int k = pos - pages.at(i).offset;
        if (k>=0 && k< pages.at(i).data.size()) {
            pages.enqueue(pages.takeAt(i));
            return pages.back().data.at(k);
        }
    }

    Page newPage;
    newPage.offset = (pos/kPageSize)*kPageSize;
    file.seek(newPage.offset);
    newPage.data = file.read(kPageSize);
    pages.push_front(newPage);

    while (pages.count()>maxPageCount)
        pages.dequeue();

    return newPage.data.at(pos - newPage.offset);
}

qint64 LargeFileCache::FileSize() const
{
    return fileSize;
}

void LargeFileCache::SetFileName(const QString &filename)
{
    file.close();
    pages.clear();
    file.setFileName(filename);
    file.open(QFile::ReadOnly);
    fileSize = file.size();
}

由于我正在处理行数据,因此我手动编写了缓存,但是您可以使用QCache http://doc.qt.io/qt-5/qcache.html这应该可以帮助您执行缓存逻辑。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

海量文本数据分割算法 的相关文章

  • 在 LINQ 查询中进行转换

    是否可以在 LINQ 查询中进行强制转换 为了编译器的缘故 下面的代码并不糟糕 但最好将其放入一个查询中 Content content dataStore RootControl as Controls Content List
  • 使用管道在父级和子级之间传递整数值

    我对如何正确使用 pipeline 在两个进程之间传递整数值有点困惑 在我的程序中 我首先创建一个管道 然后分叉它 我假设我有 两个 管道 据我了解 这是我的任务 我的父母通过 for 循环检查某个操作的整数值 i 增加计数变量 并将值保存
  • 如何从经过身份验证的 SecurityToken 中获取声明

    我将令牌作为字符串传递到 SOAP 服务中 并验证了该令牌是否有效 我现在有一个 SecurityToken 在调试模式下我可以看到所有声明 特别是我想传递到另一个方法的 userId 声明 我似乎不知道如何获得这些索赔 现在 我解码了令牌
  • 从结构调用 C++ 成员函数指针

    我找到了有关调用 C 成员函数指针和调用结构中的指针的信息 但我需要调用结构内部存在的成员函数指针 但我无法获得正确的语法 我在类 MyClass 的方法中有以下代码片段 void MyClass run struct int MyClas
  • 如何以编程方式删除受信任的根证书颁发机构中的证书?

    我需要能够从组织中的每台电脑中删除特定的证书 是的 我可以逐个座位 但我要到周四才能完成 而且我没有人力逐个座位 是否有使用 C 的编程方式来执行此操作 我认为你不需要编写任何 C 看看certmgr exe del http msdn m
  • 如何在 C# 中以编程方式将行添加到 DataGrid?

    正如标题所述 我正在尝试使用 C 以编程方式将行添加到 DataGrid 但我似乎无法使其工作 这是我到目前为止所拥有的 I have a DataGrid declared as dg in the XAML foreach string
  • 如何在 Linux 上重新实现(或包装)系统调用函数?

    假设我想完全接管 open 系统调用 也许要包装实际的系统调用并执行一些日志记录 一种方法是使用 LD PRELOAD http scaryreasoner wordpress com 2007 11 17 using ld preload
  • 在 C# 中解析 JS Date.toIsoString

    我需要将 JS 日期存储为 ISO 8601 日期 我目前正在从格式为 2019 06 22T00 00 00 000Z 的表单中获取日期 正如 JS 的 toIsoString 方法所期望的那样 当这个日期传递到我的 API 控制器时 我
  • 从图像创建半透明光标

    是否可以从图像创建光标并使其半透明 我目前正在拍摄自定义图像并覆盖鼠标光标图像 如果我可以将其设为半透明 那就太好了 但不是必需的 销售人员喜欢闪亮的 目前正在做这样的事情 Image cursorImage customImage Get
  • 注入包含接口的所有已注册实现的 Enumerable

    给出以下接口 public interface IMyProcessor void Process 我希望能够注册多个实现 并让我的 DI 容器将它们的可枚举注入到这样的类中 public class MyProcessorLibrary
  • 为什么连续抛出 2 个异常不会生成无法访问的代码警告?

    为什么以下代码行不会创建编译器警告 void Main throw new Exception throw new Exception 据我所知 编译器应该通知您无法到达第二个抛出异常 这显然是一个编译器错误 它是在 C 3 0 中引入的
  • 将 AutomationID 与 ListView 结合使用

    我正在尝试将 AutomationId 附加到列表视图中的项目 理想情况下 将项目名称绑定到显示的项目
  • 如何在VS2005中使用从.bat而不是.exe启动的外部程序进行调试?

    在我的 c 项目的调试属性中 我选择了 启动外部程序 并选择了我希望将调试器附加到的程序的 exe 但是 现在我需要从 bat 文件而不是 exe 启动程序 但 VS2005 似乎不允许这样做 这可能吗 编辑 为了澄清 我需要调试从 bat
  • 在 Visual Studio 2012 Express 中设置 C++ 调试环境

    我需要调试的应用程序需要设置环境变量 这在 Visual Studio 2012 中似乎非常复杂 我想做类似的事情 set path c foo c bar c windows c program files application set
  • 让 Windows 尝试读取文件

    我正在对 Windows 文件系统进行某种封装 当用户请求打开文件时 Windows 调用我的驱动程序来提供数据 在正常操作中 驱动程序返回缓存的文件内容 但是 在某些情况下 实际文件没有缓存 我需要从网络下载它 问题是是否有可能让 Win
  • Windows Phone 的 JSON 反序列化

    我正在尝试反序列化以下 JSON 但我真的不知道如何使用 JSON net 来完成这项工作 我正在使用 C 和 JSON Net 库 我的 JSON 如下 found 3 bounds 43 54919 172 62148 43 54487
  • 在多线程环境中捕获信号

    我有一个大型程序 需要尽可能具有弹性 并且有大量线程 我需要捕获所有信号SIGBUS SIGSEGV 并在必要时重新初始化有问题的线程 或者禁用该线程以继续减少功能 我的第一个想法是做一个setjump 然后设置信号处理程序 可以记录问题
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • 使用通用存储库模式和流畅的 nHibernate

    我目前正在开发一个中型应用程序 它将访问不同站点上的 2 个或更多 SQL 数据库等 我正在考虑使用类似的东西 http mikehadlow blogspot com 2008 03 using irepository pattern w
  • 如何使用 Microsoft Graph API 更新 MailboxSettings

    我想从不同的日历更新邮箱设置 如何构建可以通过 Microsoft Graph 更新 MailboxSetting 的请求 这是我的代码示例 但有例外 代码示例 User obj GraphServiceClient Users roomC

随机推荐