一段直接路径读取文件LINUX C代码

最近搞个MYBATIS-PLUS里面的MAPPER DAO方法审计.就是把里面的SQL提取出来,然后使用SQL质量工具进行审计! 
SQLE 在这方面功能强大,就是细节不够完美,它有SCANDR工具可以把某个目录下XML文件扫描并上传到SQLE里面进行审计.
通过自由裁剪的MYSQL 审核规则,一条条SQL进行! 问题是那么多SQL,不符合规范的是来之哪个文件,哪个方法?

像这样子就满意了

我通过提示方式来判断这个SQL来之哪里

SCANDER工具 它扫描 上传 显示是否通过,不通过显示是哪条规则,最后总是报个错误出来. 

社区版也就这样,功能超强,细节不完美,要完美估计要买企业版.

所以作为一个初级程序员 之 C 就只好自己动手丰衣足食了!

经过3周,3个周的工作日,加班2个小时到8点,才初步成型. 上班时间要干其它活,只要下班,才能专心写代码,调试代码.

下面一段是用直接IO读写文件,就是绕过LINUX的系统缓存. 

PG一大BUG 就是使用双缓存,导致某些SQL执行时快时慢,对DBA要精细调整两边的缓存比! MYSQL和ORACLE不这样干!

PG   ACE 大部分没有代码动手的能力,有PPT,文档编辑能力以及演讲口才能力. 

要使用DIO需要3个小条件
1 需要堆上分配
2 需要512字节对齐
3 需要4KB整数倍写入文件

下面代码开始大部分是在程序当前目录下创建一个XXX.SQL文件,
有就只写,追加,直接,同步方式写入数据.
int fd = open(filePath,  O_CREAT | O_APPEND | O_WRONLY | O_DIRECT | O_SYNC, 0644);

从双层MAP对象里提取出SQL
MAP<STRING,MAP<STRING,STRING>> OBJECT;
这个对象保存了 文件名,方法名,SQL的对应关系

定义个通用类型的内存地址变量 memAddr_buf

memAddr_buf = memalign(512, 512 * 8); 通过这个函数进行512字节对齐,对4096字节,它自动在堆上分配4096字节

memcpy(memAddr_buf, it->second.c_str(), it->second.size()); 通过内存CP函数把MAP里的SQL拷贝进去*(char*)((char*)memAddr_buf + sql_size) = '\n'; 这段内容后面添加个换行符号,有意思的代码.是AI浣熊告知的. 然后就写入文件一次必须4KB字节倍数,成功返回写入字节,错误返回-1int   ret = write(fd, memAddr_buf, 4096);free(memAddr_buf); 最后就是释放内存. 这4个函数OPEN,WRITE,MEMALIGN,FREE都是LINUX系统提供的函数.

char current_dir[PATH_MAX];                            //创建文件 并导出SQL语句到文件里
  char fileName[]="ParseXMLFetchSQL.sql";
  char filePath[PATH_MAX];


  if(getcwd(current_dir,sizeof(current_dir)) != NULL)
  {
    if (is_debug) {printf("Current Working Directory:%s\n",current_dir);}
    strcpy(filePath, current_dir);
    strcat(filePath, "/");
    strcat(filePath, fileName);
    if (is_debug) {printf("filePath:%s\n",filePath);}

    int fd = open(filePath,  O_CREAT | O_APPEND | O_WRONLY | O_DIRECT | O_SYNC, 0644);
    if (fd == -1)
      {
        printf("Error Open File %s\n",filePath);
        close(fd);
        return 1;
      }
      else
      {
        if (is_debug) {printf("fileName Number:%d\n",filename_sql_map.size());}
        for (auto it = filename_sql_map.begin(); it != filename_sql_map.end(); ++it)
        {
          std::map<std::string,std::string> read_sql_map;
          read_sql_map = it->second;
          if (is_debug) {printf("SQL Number:%d\n",read_sql_map.size());}
          void* memAddr_buf;
          memAddr_buf = memalign(512, 512 * 8);
          if (!memAddr_buf)  {  printf("Failed to alloc write buffer\n"); free(memAddr_buf); }            

          for(auto it = read_sql_map.begin(); it != read_sql_map.end(); ++it)
          {             
            unsigned int sql_size=it->second.size();    
            memset(memAddr_buf,'\0',4096);    
            memcpy(memAddr_buf, it->second.c_str(), it->second.size());
            *(char*)((char*)memAddr_buf + sql_size) = '\n';
            int   ret = write(fd, memAddr_buf, 4096);
            if (ret == -1)
            {
              printf("Error Write File %s\n",filePath);
              close(fd);
              free(memAddr_buf);
              return 1;
            }      
          } // for sql map
          free(memAddr_buf);          
        }//for filename_sql_map 
      }
    }

下面是头文件. 有兴趣的朋友可以试试


/*
 By Sharkz(小凡仙) 曾凡坤 2024-07-08

*/

/* Standard C++ headers */

#include <iostream>  //输入输出流
#include <fstream>   //文件流
//#include <sstream>   //字符串流
#include <stdexcept> //标准异常
#include <map>       //MAP 类
#include <string>    //字符串类
//#include <chrono>    //获得纳秒时间 Calc_time_diff
#include <vector>    //动态数组
#include <cstdlib>


//C LANGE LIB
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>

//Liunx sys lib
#include <fcntl.h>    //linux 文件库
#include <unistd.h>   //进程库
#include <dirent.h>    //posix 

/*
  g++ -g main.cpp -std=c++11 -o main.exe
  ./main.exe -d /home/shark/projects/CPP_Projects/ParseXmlSql > run.log
*/

using namespace std;

写后文件内容是这样的,两个SQL中间一大段是NULL

哎 搞到高兴之处,把生产的14个SQL的文件传给SQLE进行审核,居然说语法不支持,开始我以为HINT放的位置不对, 另外SQLE还说SQL太长了,要分成多个SQL的提示. 以前直接审计XML文件,对有些超长的方法也是这样报错,我以为想当然. 直到看到一个DELETE语句 不到50个字母,也这样说,就忽然明白了什么. SQLE没有去空. 我写文件一次写入4096个字节,也可以说字符,大部分提取的SQL顶多是1500个字母,后面好几千都NULL.

哎 搞得我要放弃这段DIO,直接写文件的代码. 

心里不是个滋味!

再论国产数据库的选择

如何选择国产数据库?

基于MYSQL的JAVA初级优化措施

Oracle优化新常态

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值