开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 3472|回复: 40
收起左侧

[其它源码] 【原创】C++内存映射高速文本行删改查DLL

[复制链接]
结帖率:83% (5/6)
发表于 2023-5-27 23:13:06 | 显示全部楼层 |阅读模式   黑龙江省哈尔滨市
分享源码
界面截图:
是否带模块: 纯源码
备注说明: -
本帖最后由 xwwyt 于 2023-5-28 13:44 编辑

接上回写的文本行替换
按照各位朋友的建议写了删改查(增暂时没写)
效率很高 实测大文本秒操作
调用方法如下: QQ截图20230527224728.png 新增一个读入文本 直接返回文本型
QQ截图20230528110108.png
  
DLL命令名返回值类型公开备 注
replace_line 
DLL库文件名:
xlall.dll
在DLL库中对应命令名:
@replace_line
参数名类 型传址数组备 注
path文本型填文本文件的路径
line整数型需要替换的行
content文本型需要替换成的内容
DLL命令名返回值类型公开备 注
del_line逻辑型 
DLL库文件名:
xlall.dll
在DLL库中对应命令名:
@del_line
参数名类 型传址数组备 注
path文本型填文本文件的路径
line整数型需要删除的行
DLL命令名返回值类型公开备 注
get_line文本型 
DLL库文件名:
xlall.dll
在DLL库中对应命令名:
@get_line
参数名类 型传址数组备 注
path文本型填文本文件的路径
line整数型需要取的行
DLL命令名返回值类型公开备 注
read_text文本型 
DLL库文件名:
xlall.dll
在DLL库中对应命令名:
@read_rext
参数名类 型传址数组备 注
path文本型


文本行替换操作:
jdfw.gif
文本行删除操作:
jdfw2.gif
取文本行内容操作:
jdfw3.gif
读入文本的操作直接同理按照上方来(省略了转换到文本的麻烦)
CPP源码:
[C++] 纯文本查看 复制代码
#define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <windows.h>
#include <codecvt>
#include <locale>
//这周末只更新删改查 均用了内存映射 效率很高 编码按要求易语言调用的时候改就好 不会出现文件乱码
extern "C" __declspec(dllexport) void replace_line(char* path, int line, char* content) {
    HANDLE hFile = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr << "Could not open file" << std::endl;
        return;
    }
    HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
    if (hMapFile == NULL) {
        std::cerr << "Could not create file mapping" << std::endl;
        CloseHandle(hFile);
        return;
    }
    char* pBuf = (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
    if (pBuf == NULL) {
        std::cerr << "Could not map view of file" << std::endl;
        CloseHandle(hMapFile);
        CloseHandle(hFile);
        return;
    }

    // 检测文本中的换行符是什么 不同的系统版本可能不同
    std::string fileContent(pBuf);
    bool useCRLF = fileContent.find("\r\n") != std::string::npos;

    int currentLine = 1;
    char* p = pBuf;
    char* lineStart = pBuf;
    while (*p != '\0') {
        if (currentLine == line) {
            char* lineEnd = p;
            while (*lineEnd != '\n' && *lineEnd != '\0') {
                lineEnd++;
            }
            size_t len = lineEnd - lineStart;
            std::string newContent(content);
            if (useCRLF) {
                newContent += "\r";
            }
            size_t newLen = newContent.length();
            if (newLen > len) {
                size_t diff = newLen - len;
                size_t fileSize = GetFileSize(hFile, NULL);
                char* newBuf = new char[fileSize + diff];
                memcpy(newBuf, pBuf, lineStart - pBuf);
                memcpy(newBuf + (lineStart - pBuf), newContent.c_str(), newLen);
                memcpy(newBuf + (lineStart - pBuf) + newLen, lineEnd, fileSize - (lineEnd - pBuf));
                UnmapViewOfFile(pBuf);
                CloseHandle(hMapFile);
                SetFilePointer(hFile, fileSize + diff, NULL, FILE_BEGIN);
                SetEndOfFile(hFile);
                hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
                if (hMapFile == NULL) {
                    std::cerr << "Could not create file mapping" << std::endl;
                    CloseHandle(hFile);
                    return;
                }
                pBuf = (char*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
                if (pBuf == NULL) {
                    std::cerr << "Could not map view of file" << std::endl;
                    CloseHandle(hMapFile);
                    CloseHandle(hFile);
                    return;
                }
                memcpy(pBuf, newBuf, fileSize + diff);
                delete[] newBuf;
            }
            else {
                memcpy(lineStart, newContent.c_str(), newLen);
                memmove(lineStart + newLen, lineEnd, strlen(lineEnd) + 1);
            }
            break;
        }
        if (*p == '\n') {
            currentLine++;
            lineStart = p + 1;
        }
        p++;
    }
    UnmapViewOfFile(pBuf);
    CloseHandle(hMapFile);
    CloseHandle(hFile);
}

extern "C" __declspec(dllexport) void del_line(char* path, int line)
{
    HANDLE hFile = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        std::cerr << "Could not open file." << std::endl;
        return;
    }

    DWORD dwFileSize = GetFileSize(hFile, NULL);
    if (dwFileSize == INVALID_FILE_SIZE)
    {
        std::cerr << "Could not get file size." << std::endl;
        CloseHandle(hFile);
        return;
    }

    HANDLE hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize, NULL);
    if (hMapFile == NULL)
    {
        std::cerr << "Could not create file mapping object." << std::endl;
        CloseHandle(hFile);
        return;
    }

    LPVOID lpMapAddress = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, dwFileSize);
    if (lpMapAddress == NULL)
    {
        std::cerr << "Could not map view of file." << std::endl;
        CloseHandle(hMapFile);
        CloseHandle(hFile);
        return;
    }

    char* data = (char*)lpMapAddress;
    int currentLine = 1;
    DWORD startOffset = 0;
    for (DWORD i = 0; i < dwFileSize; i++)
    {
        if (data == '\n')
        {
            currentLine++;
            if (currentLine == line)
            {
                startOffset = i + 1;
                break;
            }
        }
    }

    DWORD endOffset = startOffset;
    for (DWORD i = startOffset; i < dwFileSize; i++)
    {
        if (data == '\n')
        {
            endOffset = i + 1;
            break;
        }
    }

    MoveMemory(data + startOffset, data + endOffset, dwFileSize - endOffset);

    UnmapViewOfFile(lpMapAddress);
    CloseHandle(hMapFile);

    SetFilePointer(hFile, dwFileSize - (endOffset - startOffset), NULL, FILE_BEGIN);
    SetEndOfFile(hFile);

    CloseHandle(hFile);
}

extern "C" __declspec(dllexport) char* get_line(char* path, int line) {
    HANDLE hFile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) return NULL;
    HANDLE hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if (hMap == NULL) {
        CloseHandle(hFile);
        return NULL;
    }
    char* pFile = (char*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0);
    if (pFile == NULL) {
        CloseHandle(hMap);
        CloseHandle(hFile);
        return NULL;
    }

    int count = 0;
    char* pLine = pFile;
    char* pEnd = pLine;
    while (*pEnd != '\0') {
        if (*pEnd == '\n' || (*pEnd == '\r' && *(pEnd + 1) == '\n')) {
            count++;
            if (count == line) break;
            pLine = pEnd + 1 + (*pEnd == '\r');
            pEnd += (*pEnd == '\r');
        }
        pEnd++;
    }
    if (count != line) {
        UnmapViewOfFile(pFile);
        CloseHandle(hMap);
        CloseHandle(hFile);
        return NULL;
    }
    int len = pEnd - pLine;

    char* result = new char[len + 1];
    memcpy(result, pLine, len);
    result[len] = '\0';

    UnmapViewOfFile(pFile);
    CloseHandle(hMap);
    CloseHandle(hFile);
    return result;
}
extern "C" __declspec(dllexport) char* read_text(char* path) {
    HANDLE hFile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
    if (hFile == INVALID_HANDLE_VALUE) return nullptr;

    DWORD fileSize = GetFileSize(hFile, nullptr);
    HANDLE hMapFile = CreateFileMapping(hFile, nullptr, PAGE_READONLY, 0, fileSize, nullptr);
    if (hMapFile == nullptr) {
        CloseHandle(hFile);
        return nullptr;
    }

    char* buffer = (char*)MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, fileSize);
    if (buffer == nullptr) {
        CloseHandle(hMapFile);
        CloseHandle(hFile);
        return nullptr;
    }

    int isTextUnicode = IS_TEXT_UNICODE_UNICODE_MASK;
    IsTextUnicode(buffer, fileSize, &isTextUnicode);

    char* gbkBuffer;
    if (isTextUnicode == IS_TEXT_UNICODE_UNICODE_MASK) {
        std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
        std::wstring wide = converter.from_bytes(buffer, buffer + fileSize);
        int gbkSize = WideCharToMultiByte(CP_ACP, 0, wide.c_str(), -1, nullptr, 0, nullptr, nullptr);
        gbkBuffer = new char[gbkSize];
        WideCharToMultiByte(CP_ACP, 0, wide.c_str(), -1, gbkBuffer, gbkSize, nullptr, nullptr);
    }
    else {
        gbkBuffer = new char[fileSize + 1];
        memcpy(gbkBuffer, buffer, fileSize);
        gbkBuffer[fileSize] = '\0';
    }

    UnmapViewOfFile(buffer);
    CloseHandle(hMapFile);
    CloseHandle(hFile);

    return gbkBuffer;
}
DLL+调用示例下载:https://wwwk.lanzouf.com/iR7Vs0xhnmof
希望对大家的学习有所帮助
请支持一票 谢谢



final.zip

13.52 KB, 下载次数: 62, 下载积分: 精币 -2 枚

评分

参与人数 5好评 +4 精币 +9 收起 理由
searchjack + 1 + 2 支持开源~!感谢分享
六发八门 + 2 支持开源~!感谢分享
易语言资源网 + 1 + 3 开源精神必须支持~
光影魔术 + 1 + 1 支持开源~!感谢分享
默念、 + 1 + 1 支持开源~!感谢分享

查看全部评分


结帖率:78% (7/9)

签到天数: 14 天

发表于 2024-8-20 10:42:12 | 显示全部楼层   辽宁省沈阳市
这个好 这个好  
回复 支持 反对

使用道具 举报

结帖率:60% (3/5)

签到天数: 8 天

发表于 2024-6-7 00:27:52 | 显示全部楼层   四川省成都市
感谢大大分享 , 厉害
回复 支持 反对

使用道具 举报

发表于 2023-6-12 16:33:00 | 显示全部楼层   福建省莆田市
希望对大家的学习有所帮助 请支持一票 谢谢
回复 支持 反对

使用道具 举报

发表于 2023-6-4 10:02:57 | 显示全部楼层   浙江省台州市
        感谢分享
回复 支持 反对

使用道具 举报

发表于 2023-6-3 21:39:36 | 显示全部楼层   江苏省连云港市
支持开源~!感谢分享
回复 支持 反对

使用道具 举报

结帖率:0% (0/2)

签到天数: 17 天

发表于 2023-6-3 11:08:39 | 显示全部楼层   广西壮族自治区玉林市
感谢分享,很给力!~
回复 支持 反对

使用道具 举报

签到天数: 20 天

发表于 2023-6-2 08:46:24 | 显示全部楼层   黑龙江省哈尔滨市
学习一下!!!
回复 支持 反对

使用道具 举报

结帖率:83% (5/6)
 楼主| 发表于 2023-6-1 16:17:37 | 显示全部楼层   美国

可能会出问题
回复 支持 反对

使用道具 举报

结帖率:0% (0/3)

签到天数: 1 天

发表于 2023-6-1 08:27:19 | 显示全部楼层   湖北省武汉市

是win7系统
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表