MDFS格式数据转换

Cython

This article was last updated on <span id="expire-date"></span> days ago, the information described in the article may be outdated.

最近要读取 MDFS 格式的气象站点数据在 Python 中使用,但是由于其数据格式不是标准的 JSON ,需要用脚本进行转换。于是我去学校网站下载了一个写好的 Python 脚本,但是运行一遍之后发现不仅需要我额外下载 JSON 的库,而且转换一个文件竟然要 368秒 ???

为了提升效率,我就用 C + Cython 写了一个速度更快的。

数据格式

就是下面这个样子,为什么不直接存成 JSON 呢

代码

废话不多说,直接贴代码

C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <string.h>

int fk_mdfs(char* filename, char* savename)
{
FILE *fid = fopen(filename, "r");
FILE *wfid = fopen(savename, "w");
char text[2];
char quotation[] = "\"";
char colon[] = ":";
// 这里是判断,给键名加上引号 ""
while(!feof(fid))
{
fread(text, 1, 1, fid);
if(!strcmp(text, "{"))
{
fwrite(text, 1, 1, wfid);
fwrite(quotation, 1, 1, wfid);
}
else if (!strcmp(text, "="))
{
fwrite(quotation, 1, 1, wfid);
fwrite(colon, 1, 1, wfid);
}
else if (!strcmp(text, " "))
{
fwrite(text, 1, 1, wfid);
fwrite(quotation, 1, 1, wfid);
}
else
{
fwrite(text, 1, 1, wfid);
}
}

fclose(fid);
fclose(wfid);
return 0;
}

Cython

1
2
3
4
5
6
cdef extern from "main.c":
int fk_mdfs(char* filename, char* savename)

# 包装 C 函数
def FkMdfs(filename, savename):
fk_mdfs(filename.encode('UTF-8'), savename.encode('UTF-8'))
注意

C 语言代码只实现了处理单个文件的功能,而且文件前 5 行的文件头已默认去掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from fk_msdf import FkMdfs
from os import listdir

path = '../SURFACE/RAIN01_ALL_STATION/'
filenames = [x for x in listdir(path) if 'txt' in x]
for filename in filenames:
# 去除前 5 行的文件头
with open(path + filename, 'r') as f:
for i in range(5):
f.readline()
text = f.read()
with open('.tmp', 'w') as f:
f.write(text)
FkMdfs('.tmp', path + 'json/' + filename[10:-4] + '.json')

运行时间

效率直接提升 28 万倍

Author: Syize

Permalink: https://blog.syize.cn/2022/04/22/MDFS-data/

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Syizeのblog

Comments