较大数据文件的读取优化过程

用CFile类读取大文件 随着Windows 2000和XP的普及,现在的大文件越来越多,而VC6中MFC的CFile类只支持不大于4GB的文件, 原因在于CFile类中使用了32位整型来处理文件,32位数的范围是2的32次方(4GB),超过这个范围的文件CFile就管不了,微软.Net中VC7的CFile类支持大于4GB的文件,而.Net还不普及,开发桌面应用VC6还是首选,所以我们可以参照VC7写一个CFile的继承类 阅读详情

问题由来

1.解析一个体积较大(50MB,约50w行)的数据文件时,遇到了读取、解析花费的时间较长(debug下20+s,release下3s)速度较慢的问题。
2.用UE或者everedit等编辑软件打开这种文件基本上只要0.5s不到的时间。
因此尝试优化代码,提高效率,这里记录下过程。

测试平台

环境

win10x64 + VS2015

文件格式

数据文件分为三段:

第一段 230000 250000
第二段开始 1 115.853843 22.534526 -47.04851444
………….
第二段结束 230000 ………………………
第三段开始 1 3 2 96 1 0
………………………..
第三段结束 250000 ………………….

处理过程

基本方法

最基本的MFC读数据方式:CStdioFile打开文件-Readstring读取每行数据-查找分隔符-分割出字符串-转化为浮点数-保存到数组里去。

void CGRDFile::OpenStdioFile(CString sFileName)
{
    CStdioFile m_file; 
    m_file.Open(sFileName, CFile::modeRead);

    Vertex v;
    MeshIndex mesh;
    CString smn, sm, sn,sVertex, sN, sX, sY, sZ, sLeft, sMesh, s1Index, s2Index, s3Index;

    m_file.ReadString(smn);
    smn.Trim();

    sm = smn.Left(smn.Find(' '));
    sn = smn.Mid(smn.Find(' '), smn.GetLength() - 1);
    sn.Trim();

    m_grdFile.mn.m = _wtoi(sm);
    m_grdFile.mn.n = _wtoi(sn);
    //预分配数组大小
    m_grdFile.vVertex.reserve(m_grdFile.mn.m);
    m_grdFile.vMeshIndex.reserve(m_grdFile.mn.n);
    //第二段处理
    for (int i = 0; i < m_grdFile.mn.m; i++)
    {
        m_file.ReadString(sVertex);

        sVertex.Trim();
        sN = sVertex.Left(sVertex.Find(' '));
        sLeft = sVertex.Right(sVertex.GetLength() - sN.GetLength());
        sLeft.Trim();

        sX = sLeft.Left(sLeft.Find(' '));
        sLeft = sLeft.Right(sLeft.GetLength() - sX.GetLength());
        sLeft.Trim();

        sY = sLeft.Left(sLeft.Find(' '));
        sLeft = sLeft.Right(sLeft.GetLength() - sY.GetLength());
        sLeft.Trim();

        sZ = sLeft;

        v.nIndex = _wtoi(sN);
        v.x = _wtof(sX);
        v.y = _wtof(sY);
        v.z = _wtof(sZ);

        m_grdFile.vVertex.push_back(v);
        //第三段处理类似,不贴了
    }

经过测试上面的代码在release下读取完数据耗时2779.03ms在debug下耗时21122ms。

内存文件映射法

内存文件映射是一个提高大文件读取速度的方法。

void CGRDFile::OpenFile(CString sFileName)
{
    HANDLE hFile = CreateFile(
        sFileName,
        FILE_SHARE_READ ,
        0,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {

        return ;
    }
    HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (hFileMap == NULL)
    {

        return;
    }
    // 得到系统分配粒度  
    SYSTEM_INFO SysInfo;
    GetSystemInfo(&SysInfo);
    DWORD dwGran = SysInfo.dwAllocationGranularity;

    // 得到文件尺寸  
    DWORD dwFileSizeHigh;
    __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh);
    qwFileSize |= (((__int64)dwFileSizeHigh) << 32);



    // 偏移地址   
    __int64 qwFileOffset = 0;

    // 块大小 
    DWORD dwBlockBytes = 0;
    for (int i = 1; ; ++i)
    {
        if (qwFileSize <= i * dwGran)
        {
            dwBlockBytes = i * dwGran;
            break;
        }
    }
    if (qwFileOffset >= 0)
    {
        // 映射视图
        //如果在调用MapViewOfFile()的时候,dwNumberOfBytesToMap如果大于文件的size,那么该call就会失败,
        //并且error code是access denied。所以MapViewOfFile的最后一个参数不能用dwBlockSize而只能用qwFileSize。
        //MapViewOfFile的返回值不能是TCHAR*,因为UNICODE时解释成宽字符,会出错,只能用char*
        char *lpbMapAddress = (char *)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, qwFileSize);
        if (lpbMapAddress == NULL)
        {           
            return;
        }
        CString stemp(lpbMapAddress);
        CString smn,sm, sn;

        smn = stemp.Left(stemp.Find('\n'));
        smn.Trim();
        sm = smn.Left(smn.Find(' '));
        sn = smn.Mid(smn.Find(' '), smn.GetLength() - 1);
        sn.Trim();

        m_grdFile.mn.m = _wtoi(sm);
        m_grdFile.mn.n = _wtoi(sn);
        //预分配数组大小
        m_grdFile.vVertex.reserve(m_grdFile.mn.m);
        m_grdFile.vMeshIndex.reserve(m_grdFile.mn.n);
        //顶点数组
        Vertex v;
        CString sVertex, sN, sX, sY, sZ, sLeft;

        int nStart, nEnd;
        nStart = stemp.Find('\n');
        nEnd = stemp.Find('\n', nStart + 1);
        for (int i = 0; i < m_grdFile.mn.m; i++)
        {
            sVertex = stemp.Mid(nStart+ 1, nEnd - nStart + 1);

            sVertex.Trim();
            sN = sVertex.Left(sVertex.Find(' '));
            sLeft = sVertex.Right(sVertex.GetLength() - sN.GetLength());
            sLeft.Trim();

            sX = sLeft.Left(sLeft.Find(' '));
            sLeft = sLeft.Right(sLeft.GetLength() - sX.GetLength());
            sLeft.Trim();

            sY = sLeft.Left(sLeft.Find(' '));
            sLeft = sLeft.Right(sLeft.GetLength() - sY.GetLength());
            sLeft.Trim();

            sZ = sLeft;

            v.nIndex = _wtoi(sN);
            v.x = _wtof(sX);
            v.y = _wtof(sY);
            v.z = _wtof(sZ);

            m_grdFile.vVertex.push_back(v);

            nStart = stemp.Find('\n', nEnd);
            nEnd = stemp.Find('\n', nStart + 1);
        }
        //网格数组
        CString sMesh, s1Index, s2Index, s3Index;
        MeshIndex mesh;
        for (int i = 0; i < m_grdFile.mn.n; i++)
        {
            sMesh = stemp.Mid(nStart + 1, nEnd - nStart + 1);

            sMesh.Trim();
            sN = sMesh.Left(sMesh.Find(' '));
            sLeft = sMesh.Right(sMesh.GetLength() - sN.GetLength());
            sLeft.Trim();

            s1Index = sLeft.Left(sLeft.Find(' '));
            sLeft = sLeft.Right(sLeft.GetLength() - s1Index.GetLength());
            sLeft.Trim();
            s1Index = sLeft.Left(sLeft.Find(' '));
            sLeft = sLeft.Right(sLeft.GetLength() - s1Index.GetLength());
            sLeft.Trim();

            s2Index = sLeft.Left(sLeft.Find(' '));
            sLeft = sLeft.Right(sLeft.GetLength() - s2Index.GetLength());
            sLeft.Trim();

            s3Index = sLeft.Left(sLeft.Find(' '));

            mesh.nIndex = _wtoi(sN);
            mesh.nV1Index = _wtoi(s1Index);
            mesh.nV2Index = _wtoi(s2Index);
            mesh.nV3Index = _wtoi(s3Index);

            m_grdFile.vMeshIndex.push_back(mesh);

            nStart = stemp.Find('\n', nEnd);
            nEnd = stemp.Find('\n', nStart + 1);
        }


        // 撤销文件映像
        UnmapViewOfFile(lpbMapAddress);
        // 关闭文件对象  
        CloseHandle(hFile);
    }



}

经过测试上面的代码在release下读取完数据耗时1437.46ms在debug下耗时13738ms。

再优化下

仔细观察了数据文件,每行占的字节数、每个值占得字节数其实是都是确定的,利用这个特点,可以避免循环里非常复杂耗时的字符串解析过程。

//内存文件映射部分代码不贴了,和上面一样
        Vertex v;
        MeshIndex mesh;
        CString smn, sm, sn, sVertex, sN, sX, sY, sZ, sLeft, sMesh, s1Index, s2Index, s3Index,sblank;
        smn = stemp.Left(MN_LINE_SIZE);
        smn.Trim();

        sm = smn.Mid(0, MN_M_CHAR_SIZE);
        sn = smn.Mid(MN_M_CHAR_SIZE, MN_N_CHAR_SIZE);

        m_grdFile.mn.m = _wtoi(sm);
        m_grdFile.mn.n = _wtoi(sn);
        //预分配数组大小
        m_grdFile.vVertex.reserve(m_grdFile.mn.m);
        m_grdFile.vMeshIndex.reserve(m_grdFile.mn.n);
        //顶点数组
        for (int i = 0; i < m_grdFile.mn.m; i++)
        {
            sVertex = stemp.Mid(MN_LINE_SIZE + i * VERTEX_LINE_SIZE, VERTEX_LINE_SIZE);
            sN = sVertex.Mid(0, VERTEX_N_CHAR_SIZE);
            sX = sVertex.Mid(VERTEX_N_CHAR_SIZE , VERTEX_X_CHAR_SIZE);
            sY = sVertex.Mid(VERTEX_N_CHAR_SIZE + VERTEX_X_CHAR_SIZE , VERTEX_Y_CHAR_SIZE);
            sZ = sVertex.Mid(VERTEX_N_CHAR_SIZE + VERTEX_X_CHAR_SIZE + VERTEX_Y_CHAR_SIZE, VERTEX_Z_CHAR_SIZE);

            v.nIndex = _wtoi(sN);
            v.x = _wtof(sX);
            v.y = _wtof(sY);
            v.z = _wtof(sZ);

            m_grdFile.vVertex.push_back(v);
        }
        //网格数组
        for (int i = 0; i < m_grdFile.mn.n; i++)
        {
            sMesh = stemp.Mid(MN_LINE_SIZE + m_grdFile.mn.m * VERTEX_LINE_SIZE + MESH_LINE_SIZE * i , 
                MESH_LINE_SIZE);
            sN = sMesh.Mid(0, MESH_N_CHAR_SIZE);
            s1Index = sMesh.Mid(MESH_N_CHAR_SIZE + MESH_NODEFINE_CHAR_SIZE , MESH_V1_CHAR_SIZE);
            s2Index = sMesh.Mid(MESH_N_CHAR_SIZE + MESH_NODEFINE_CHAR_SIZE + MESH_V1_CHAR_SIZE , MESH_V2_CHAR_SIZE);
            s3Index = sMesh.Mid(MESH_N_CHAR_SIZE + MESH_NODEFINE_CHAR_SIZE + MESH_V1_CHAR_SIZE + MESH_V2_CHAR_SIZE ,
                MESH_V3_CHAR_SIZE);

            mesh.nIndex = _wtoi(sN);
            mesh.nV1Index = _wtoi(s1Index);
            mesh.nV2Index = _wtoi(s2Index);
            mesh.nV3Index = _wtoi(s3Index);

            m_grdFile.vMeshIndex.push_back(mesh);

        }

经过测试上面的代码在release下读取完数据耗时642ms在debug下耗时4763ms。

性能比较

性能比较
从图上可以看到使用了内存文件映射后,读取性能有了较大提高,在release下解析的速度可以和UE之类的软件比较了。

文件读取性能优化 相比于每次读取一个字节或一个字符,这两个类可以一次读取多个字符,从而减少了I/O操作的次数,提高了效率。三、使用缓存在文件读取时,将读取到的数据存储在内存中,再从内存中获取数据,可以大幅提高文件读取性能。相比于传统的I/O操作,NIO提供了更加高效的文件读取方式。// 将文件分割成4个块,每个线程负责读取一个块的数据for (int i = 0;四、控制文件读取的块大小在文件读取时,可以通过控制读取的块大小来提高性能。根据文件的大小和读取的需求,合理选择块大小,可以在一定程度上优化文件读取性能。 阅读详情

相关推荐

Python 文件读取操作详解

open()函数:用来打开文件,返回文件对象。常用读取方法read():读取整个文件内容。readline():按行读取文件。:读取文件的所有行,返回一个列表。with语句:自动关闭文件,避免忘记关闭文件而造成资源泄漏。文件模式:根据需要选择合适的文件打开模式,如'r''w''a'等。优化读取:对于大文件,使用逐行读取或缓冲区来优化内存使用。异常处理:处理文件操作中的常见错误,如文件不存在或权限问题。

m0_62599305的博客 1244

如何优化大文件读取时的性能

1、如果你的应用是多线程的,并且文件可以被独立地划分为多个部分,那么可以使用多个线程或进程同时读取和处理文件的不同部分。1、不要一次性将整个文件加载到内存中,而是将其分割成多个较小的块(例如,每块1MB或更大),然后逐块读取和处理。1、使用性能监视工具(如JProfiler、VisualVM等)来监视你的应用的性能,并找出可能的瓶颈。2、确保你的系统有足够的RAM和适当的磁盘I/O带宽来支持大文件的读取。1、根据你的应用的需求,调整JVM的堆大小和其他相关参数。2、确保JVM有足够的内存来处理大文件。

DKPT的博客 1608

用CStdioFile读写文件

文档讲述了使用CStdioFile对文件进行读写的方法与代码

超大文件读取性能最佳方案

超大文件读取

qq_41737501的博客 749

利用mininet模拟SDN架构并进行DDoS攻击与防御模拟(Ryu+mininet+sflow+postman)

1、知识概述 (1)软件定义网络: (2)mininet: Mininet是一个强大的网络仿真平台,通过这个平台,我们可以很方便的模拟真实环境中的网络操作与架构。特别是SDN,在真实网络中进行相关的网络实验有一定难度,自然需要一个仿真平台可以学习这种新型的网络架构,而Mininet就应运而生,承担了这个光荣而艰巨的使命。Mininet自带交换机(switchs)、主机(hosts)、控制器(controllers),同时,在mininet上可以安装OpenvSwitch、多种控制器(NOX\POX

北风 1万+

webview腾讯x5内核离线安装

离线集成腾讯TBS浏览器服务,彻底解决官方下载限流问题,永久免费

观千剑而后识器,操千曲而后晓声。 7913

Spark 大/小文件读取优化

问题描述 使用Spark写复杂SQL时,我们经常会遇到两个尴尬的情况: 表里的单个文件都很大,而且因为record比较小,所以单个文件的record数量巨大。 表里每个分区都有成百上千个小文件,单个文件可能只有几条记录 对于第一种情况,会导致我们没办法充分利用我们已有的核,所以速度很慢。 对于第二种情况,则会大量浪费调度时间。比如你有100万个文件,假设只有100个核,那么需要调度一万轮,每轮调度除了调度自身的消耗,还有很多额外的消耗。在没有shuffle的情况下,会导致写太多文件,本身...

mojolang 3582

GD32F427移植LiteOS-M实战:如何快速复用官方Demo进行二次开发

本文详细介绍了如何在GD32F427开发板上移植LiteOS-M操作系统,通过复用OpenHarmony官方Demo快速构建RTOS工程。文章涵盖环境搭建、芯片配置迁移、中断向量表处理和外设驱动适配等关键步骤,并提供了调试技巧和二次开发进阶建议,帮助开发者高效完成移植工作。

weixin_33736048的博客 415

cfile read 最大读取限制_Read文件一个字节实际会发生多大的磁盘IO?

作者:yanfei出处:https://segmentfault.com/a/1190000037728927先讲一个作者大约7年前我在某当时很火的一个应用分发创业公司的面试小插曲,该公司安排了一个刚工作1年多的一个同学来面我,聊到我们项目中的配置文件里写的一个开关,这位同学就跳出来说,你这个读文件啦,每个用户请求来了还得多一次的磁盘IO,性能肯定差。借由这个故事其实我发现了一个问题,虽然我们中的...

weixin_39992072的博客 466

PLSQL Developer14连接Oracle详细过程

下载地址:Instant Client for Microsoft Windows (x64) 64-bit | Oracle 中国解压客户端工具到一个目录(解压文件到当前目录,自动合并成一个目录)​ 电脑(右键)→属性→高级系统设置→环境变量→系统环境变量→新建变量名:NLS_LANG 变量值: AMERICAN_AMERICA.ZHS16GBK​ 变量名:TNS_ADMIN 变量值:C:\xiaxinyu\software\Oracle\instantclient_19_10​ 在Oracle客户端(C

summer_fish的专栏 3983

航测无人机las点云数据生成DEM

“ 做航测的同僚都知道,Pix4D或者CC(ContextCapture)都可以生成DSM,往往高程点提取以及土方计算都需要用到DEM,PhotoScan软件可以提出地面点并只应用地面点连接三角网,然而分类效果差,生成的DEM不管是平整度还是精度,都不理想。而传统等高线生DEM需要耗费较长时间,以下提供一种参考方法,供大家探讨。 ” 1 点云数据 航测类软件大多可以生成点云数据,如Pix4D,PhotoScan,CC等,此次点云数据为citymapper2相片基于CC生产的Las点云。 2 筛选地面点 筛.

qq_43173805的博客 1万+

较大数据文件的读取优化过程续

由来在上一篇博客(见参考1)中写了从基本到优化的过程,但仍然有可以优化的余地,这里记录下。问题文章1中根据固定行字节数优化读取速度有很大的弊端,就是需要解析的文件可能是不规则行长度的。可以有通用的按行解析的方法。当然前提仍然是基于内存映射文件。这里操作一个dat文件,共分n段,数据以空格分隔,行以\r\n分隔,大部分段平均每行大约10个双精度浮点数,小部分整数。共180w行,300MB大小。char

小猿一枚的专栏 1993

@transactional滥用导致数据源连接池耗尽问题

@transactional滥用导致数据源连接池耗尽问题

qq_43205267的博客 1201

fltk动态分配数据显示图像

fltk中在控件上显示图像可以使用生成静态数组的方式,用的时候直接加载显示即可,但是这种方式对于只是开始时显示以后就不用的图像,静态数组不能随后释放,特别是在图像比较大时会占用大量的内存。 可以使用fluid将图像转换的静态数组转换为图像数据,在使用的时候读入,用完之后释放,这样就可以节省一部分资源。 下面是一个将fluid生成的图像数据静态数组转换为数据文件然后在使用时加载的例子。 ...

Chinamming的专栏 282

openGauss学习笔记-280 openGauss性能调优-实际调优案例09-修改启动参数解决TPCC大幅度波动

openGauss学习笔记-280 openGauss性能调优-实际调优案例09-修改启动参数解决TPCC大幅度波动280.1 现象描述280.2 优化分析 openGauss学习笔记-280 ope

超哥的博客 309

Python 爬虫实战:全国高校录取分数线数据爬取与院校对比分析

本文介绍了一个基于Python的高考志愿填报辅助系统,通过爬取掌上高考平台的全国高校录取分数线数据,构建本地数据库并实现智能分析。系统主要功能包括:1)使用requests+BeautifulSoup爬取院校基本信息和历年分省分科类录取线;2)通过SQLite实现数据持久化与增量更新;3)利用pyecharts生成分数线趋势图、院校对比雷达图等可视化图表;4)提供"冲稳保"三档智能选校推荐。技术栈涵盖网络爬虫、数据清洗、数据库管理和可视化分析,可为考生提供数据驱动的志愿填报决策支持。项目采用模块化设计,包含

u014481728的博客 238

Oracle 删除数据后释放数据文件所占磁盘空间(表空间降高水位)

测试的时候向数据库中插入了大量的数据,测试完成后删除了测试用户以及其全部数据,但是数据文件却没有缩小。经查阅资料之后发现这是 Oracle “高水位”所致,那么怎么把这些数据文件的大小降下来呢?解决办法如下: 概念: 表空间的相关知识请见这里,详细的介绍了 Oracle 数据库的存储结构。 高水位:High Water Mark (HWM),是段(Segment)的一个指标,界定了段(Segment)曾经配置过的 block 水位。 据说,随着数据的 insert,所使用段(Segment)的数据块

liujinwei2005的专栏 2698

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

优化Pytorch框架的数据加载过程

queue模块 参考链接:https://www.cnblogs.com/skiler/p/6977727.html https://blog.youkuaiyun.com/qq_41185868/article/details/80502072 queue模块是python自带的模块。实现了多生产者,多消费者的队列。当要求信息必须在多线程间安全交换,这个模块在线程编程时非常有用。Queue模块实现了所有要求...

winycg的博客 5071

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【Java难点攻克】「大文件处理系列」让我们一起去挑战一下如何读取一个较大或者超大的数据文件

Java在JDK 1.4引入了ByteBuffer等NIO相关的类,使得 Java 程序员可以抛弃基于 Stream ,从而使用基于 Block 的方式读写文件,java io操作中通常采用BufferedReader,BufferedInputStream等带缓冲的IO类处理大文件,不过java nio中引入了一种基于MappedByteBuffer操作大文件的方式,其读写性能极高,本文会介绍其性能如此高的内部实现原理,分析一下到底是 FileChannel 快还是 MappedByteBuffer 块。

世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。 1952

用Python对体积较大的CSV文件进行比较的经验

用Python对体积较大的CSV文件进行比较的经验 用Python对体积较大的CSV文件进行比较的经验 » 进化的测试 | 进化的测试用Python对体积较大的CSV文件进行比较的经验python Add comments八 032010 最近的工作总是跟数据...

438

关于 3.0 和 2.0 的数据文件差异以及性能优化思路

如果需要对数据库性能优化,了解数据文件的存储方式和工作原理是必要的。

涛思数据 691

Oracle 删除数据后释放数据文件所占磁盘空间

转载:http://www.cnblogs.com/gaoyuchuanIT/articles/4151231.html 测试的时候向数据库中插入了大量的数据,测试完成后删除了测试用户以及其全部数据,但是数据文件却没有缩小。经查阅资料之后发现这是 Oracle “高水位”所致,那么怎么把这些数据文件的大小降下来呢?解决办法如下: 概念: 表空间的相关知识请见这里,详细的介绍了 Ora

Quincylk的专栏 3664

Oracle 释放(恢复)数据文件大小

今天在测试数据量占用磁盘空间大小的时候遇到问题,当插入大量数据进入数据库后,数据文件变大,但是删除以后,数据文件大小不变,这里有解决办法。 经查阅资料之后发现这是 Oracle “高水位”所致,那么怎么把这些数据文件的大小降下来呢? 概念: 表空间的相关知识请见这里http://www.cnblogs.com/fnng/archive/2012/08/12/2634485.html,

java 847

读书笔记--python数据可视化--003_读取定宽数据文件

如果文件中的格式是以定宽的格式存储的,那么可以通过格式来匹配并提取数据。一种方法是逐行读取数据,然后利用字符串的操作来提取数据。这种方法比较直接,如果在性能不做要求的话是首选操作。另外一种是利用python的struct模块来提升性能,并能读取较大的数据(比如几百兆的数据),因为这个模块使用c语言而不是python实现的。struct模块是python标准库的一部分,因此不需安装就能够使用。#-*-

HH的专栏 1063
上一篇: MFC+Direct2D以屏幕中心为中心缩放的实现
下一篇: D2D画箭头的例子
洗洗睡去
博客等级 码龄19年 277粉丝 90原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值