1.使用环境
python版本:3.8
vs版本:2017
2.功能介绍
功能:使用c语言读取comtrade的512个通道10秒的文件。本人测试:使用本代码一次读取最大耗时1.3秒,而采用Python独立读取comtrade需要耗时约20-30秒;采用python自带pyComtrade模块,需要耗时约200-300秒
测试结果:
3.c语言读取dat文件代码
/**
* @description: 解析.DAT文件
* @param {fileName:文件名,cfgFile_Header:配置文件句柄,anaData:模拟量数据,degiData:状态量数据}
* @return: false:打开文件错误,true:解析成功
*/
bool analy_DATile(char *fileName, CFGFILE_HEADER *cfgFile_Header, short ptr_ana[][SAMPLE_MAX], int *iTime)
{
FILE *fp = NULL;
int i, j, x, y;
uint16 dData;
uint32 num, time;
int iFlag = 0;//大小端标志
int cmp, cnt, dNum = 0;
char datFileName[100];
iFlag = judge_bigend_littleend();
cnt = strlen(fileName);
strncpy(datFileName, fileName, cnt - 4);
sprintf(datFileName + cnt - 4, ".dat");
#if 0
//DAT文件为ASCII码
cmp = strcasecmp(cfgFile_Header->fileFmt, "ASCII"); //忽略两个字符串中的大小写比较字符串
//printf("DATFILE name is %s,%d\n",datFileName,cmp);
if (cmp == 0) {
if ((fp = fopen(datFileName, "r")) == NULL) {
printf("open DATFile error!\n");
return false;
}
fseek(fp, 0L, SEEK_SET);//定义到文件开头
for (cnt = 0; cnt < cfgFile_Header->endsamp; cnt++) { //通道的最末采样数
fscanf(fp, "%d,%d", &num, &time); //去掉序号,时标
for (i = 0; i < cfgFile_Header->at; i++) { //读取模拟量
fscanf(fp, ",%d", anaData++);
}
for (i = 0; i < cfgFile_Header->dt; i++) { //读取数字量
fscanf(fp, ",%d", degiData++);
}
}
}
#endif
//DAT文件为BINARY码
cmp = strcasecmp(cfgFile_Header->fileFmt, "BINARY"); //忽略两个字符串中的大小写比较字符串
printf("DATFILE name is %s,%d\n", datFileName, cmp);
if (cmp == 0) {
if ((fp = fopen(datFileName, "rb")) == NULL)
{
printf("open DATFile error!\n");
return false;
}
fseek(fp, 0L, SEEK_SET);//定义到文件开头
#if 1
for (cnt = 0; cnt < cfgFile_Header->endsamp; cnt++) {
fread(&num, sizeof(uint32), 1, fp); //序号
if (iFlag == 1)
{
num = swapInt32(num);
}
fread(&time, sizeof(uint32), 1, fp); //时标
if (iFlag == 1)
{
iTime[cnt] = swapInt32(time);
}
//printf("cnt=%d,cfgFile_Header->at=%d\n", cnt, cfgFile_Header->at);
//printf("iTime[%d]=%d\n", cnt, iTime[cnt]);
//printf("num=%d,time=%d\n",num,time);
for (i = 0; i < cfgFile_Header->at; i++) {//模拟量
short buf = 0;
fread(&buf, sizeof(short), 1, fp);
if (iFlag == 1)
{
ptr_ana[i][cnt] = swapInt16(buf);
}
else
{
ptr_ana[i][cnt] = buf;
}
//printf("cnt=%d,%d\n", cnt,i);
}
#if 0
x = cfgFile_Header->dt / 16; //数字量
y = cfgFile_Header->dt % 16;
for (i = 0; i < x; i++) { //遥信量大于16路
fread(&dData, sizeof(uint16), 1, fp);
for (j = 0; j < 16; j++) {
degiData[dNum++] = (char)dData & 0x0001;
dData >>= 1;
}
}
if (y > 0)
fread(&dData, sizeof(uint16), 1, fp);
for (i = 0; i < y; i++) {
degiData[dNum++] = (char)dData & 0x0001;
dData >>= 1;
}
#endif
}
#endif
}
//关闭文件
fclose(fp);
fp = NULL;
return true;
}
4.python代码
#!/bin/env python
# -*- coding: utf-8 -*-
from ctypes import *
import time
# 获取当前路径
import os
# win10下调用dll
dll = CDLL('./readComtradeDll.dll')
#参数类型定义
dataArray=((c_short*100000)*512)() #512个通道10秒数据
timeArray=(c_int*100000)()
filName=b'AEDT01_20150121_110136_000000_001.cfg'
#执行库函数
t = time.time()
sucess = dll.GetResult(filName,dataArray,timeArray)
print(f'读取文件耗时:{time.time() - t:.4f}s')
'''
print("_____以下为python端输出______")
for i in range(100000):
print("i:",i,"timeArray:",timeArray[i])
'''