现需要对大数据文件(FileData.bin)进行快速处理,FileData.bin为二进制数据文件 (10G-1T)
已知数据结构如下
typedef struct
{
unsigned _int32 TYPE; // 数据类型
unsigned _int64 RtcTime; //数据产生时间
unsigned _int32 DataOffset;//数据偏移信息
unsigned _int32 DataLen;//数据长度
}MsgInfo;
在FileData.bin文件中随机存放了不同类型(TYPE)的结构数据,现在需要将FileData.bin文件中的数据按照不同的TYPE生成多个(TYPE).bin的文件
我理解的题意以及问题:他要按照结构体里面的TYPE分类写进不同的bin文件,结构体还要紧挨着对应的DATA。
可是按照一块一块读。从哪里读。预读多长怎么计算啊。他Data在哪里怎么找到啊。这个数据偏移信息是怎么用的啊。
第一次接触这种处理文件的题。希望大大们指点下。。最好给个马帮助理解下这类题的处理方式,伪马也可以的。
15 个解决方案
#1
HELP PLZ QWQ
#2
说清楚文件格式,然后按照格式解析就行。
#3
题目只有这么多信息。。还有一个图片。
#4
想到先读一个结构体。再用OFFSET读一个数据。。处理完了读下一个结构体下一个数据。。这样子。。可是这样子很慢啊。。1T要处理到什么时候。。有木大神提点一下。。
#5
使用文件映射,快速读入
#6
BZ大大。。可是题上要求要按TYPE分类。。每读一个结构体就要判断TYPE类型啊。判断完了再写入。那个映射能加快哪部分啊
#7
你这个数据偏移字段类型是unsigned _int32,你确定能表示10G-1T的文件?
#8
对哦。。
。
#9
看 #3 的图,数据是以链表形式写入的,下一步需要搞清楚这个 DataOffset 到底是指从那里的偏移,我能想到的可能是从每一个 MsgInfo 的头部或尾部偏移,不过因为 MsgInfo 的大小是定的,所以这个偏移感觉根本没啥用啊。搞清楚这点以后,从 DataOffset 读取 DataLen 的数据,然后写入相应的 type 文件即可。至于读取写入,傻做就行了。这种任务只需要遍历一次数据,内存映射什么的也帮补上忙,每个数据必须要进一次内存,然后在进一次硬盘,内存映射也不是神仙,改变不了这个事实。
#10
楼上大大。。。Msginfo大小是定的为什么OFFSET就没用了啊。。。
#11
就是你一个结构体
typedef struct
{
unsigned _int32 TYPE; // 数据类型
unsigned _int64 RtcTime; //数据产生时间
unsigned _int32 DataOffset;//数据偏移信息
unsigned _int32 DataLen;//数据长度
}MsgInfo;
就固定占了32+64+32+32这么长了。所以说offset应该是没用的。
你这里是不是说msginfo只是一个“头”性质的东西,msginfo随后紧接着dataoffset这么长的数据。
typedef struct
{
unsigned _int32 TYPE; // 数据类型
unsigned _int64 RtcTime; //数据产生时间
unsigned _int32 DataOffset;//数据偏移信息
unsigned _int32 DataLen;//数据长度
}MsgInfo;
就固定占了32+64+32+32这么长了。所以说offset应该是没用的。
你这里是不是说msginfo只是一个“头”性质的东西,msginfo随后紧接着dataoffset这么长的数据。
#12
看图上应该是楼上说的结构体是个头。。。那数据部分。。是read(msg.OFFSET,msg.DATALEN)吗
#13
当程序需要使用比如2GB~1TB左右的存储时,最简单的办法恐怕得是用文件读写模拟内存读写了吧。windows参考_fseeki64函数,linux参考fseeko64函数。
FILE *fA;fA=fopen("A","rb+");_fseeki64(fA,10000000000i64*sizeof(int),SEEK_SET);fputc(fA,0);//int A[10000000000];
int B;
_fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fread(&B,1,sizeof(int),fA);//B=A[9999999999];
_fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fwrite(&B,1,sizeof(int),fA);//A[9999999999]=B;
fclose(fA);
#14
因为我看 #3 的图,每个数据段紧跟在相应的 msg info 结构后面,用专业的术语说就是数据段起始位置距离对应 msg info 结构终止位置的偏移是 0,而且每一对都是这样的,那这个 DataOffset 里面要么就全是 0,要么就用不上。感觉怎么都没啥用。
#15
谢谢各位帮忙了
#1
HELP PLZ QWQ
#2
说清楚文件格式,然后按照格式解析就行。
#3
题目只有这么多信息。。还有一个图片。
#4
想到先读一个结构体。再用OFFSET读一个数据。。处理完了读下一个结构体下一个数据。。这样子。。可是这样子很慢啊。。1T要处理到什么时候。。有木大神提点一下。。
#5
使用文件映射,快速读入
#6
BZ大大。。可是题上要求要按TYPE分类。。每读一个结构体就要判断TYPE类型啊。判断完了再写入。那个映射能加快哪部分啊
#7
你这个数据偏移字段类型是unsigned _int32,你确定能表示10G-1T的文件?
#8
对哦。。
。
#9
看 #3 的图,数据是以链表形式写入的,下一步需要搞清楚这个 DataOffset 到底是指从那里的偏移,我能想到的可能是从每一个 MsgInfo 的头部或尾部偏移,不过因为 MsgInfo 的大小是定的,所以这个偏移感觉根本没啥用啊。搞清楚这点以后,从 DataOffset 读取 DataLen 的数据,然后写入相应的 type 文件即可。至于读取写入,傻做就行了。这种任务只需要遍历一次数据,内存映射什么的也帮补上忙,每个数据必须要进一次内存,然后在进一次硬盘,内存映射也不是神仙,改变不了这个事实。
#10
楼上大大。。。Msginfo大小是定的为什么OFFSET就没用了啊。。。
#11
就是你一个结构体
typedef struct
{
unsigned _int32 TYPE; // 数据类型
unsigned _int64 RtcTime; //数据产生时间
unsigned _int32 DataOffset;//数据偏移信息
unsigned _int32 DataLen;//数据长度
}MsgInfo;
就固定占了32+64+32+32这么长了。所以说offset应该是没用的。
你这里是不是说msginfo只是一个“头”性质的东西,msginfo随后紧接着dataoffset这么长的数据。
typedef struct
{
unsigned _int32 TYPE; // 数据类型
unsigned _int64 RtcTime; //数据产生时间
unsigned _int32 DataOffset;//数据偏移信息
unsigned _int32 DataLen;//数据长度
}MsgInfo;
就固定占了32+64+32+32这么长了。所以说offset应该是没用的。
你这里是不是说msginfo只是一个“头”性质的东西,msginfo随后紧接着dataoffset这么长的数据。
#12
看图上应该是楼上说的结构体是个头。。。那数据部分。。是read(msg.OFFSET,msg.DATALEN)吗
#13
当程序需要使用比如2GB~1TB左右的存储时,最简单的办法恐怕得是用文件读写模拟内存读写了吧。windows参考_fseeki64函数,linux参考fseeko64函数。
FILE *fA;fA=fopen("A","rb+");_fseeki64(fA,10000000000i64*sizeof(int),SEEK_SET);fputc(fA,0);//int A[10000000000];
int B;
_fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fread(&B,1,sizeof(int),fA);//B=A[9999999999];
_fseeki64(fA,9999999999i64*sizeof(int),SEEK_SET);fwrite(&B,1,sizeof(int),fA);//A[9999999999]=B;
fclose(fA);
#14
因为我看 #3 的图,每个数据段紧跟在相应的 msg info 结构后面,用专业的术语说就是数据段起始位置距离对应 msg info 结构终止位置的偏移是 0,而且每一对都是这样的,那这个 DataOffset 里面要么就全是 0,要么就用不上。感觉怎么都没啥用。
#15
谢谢各位帮忙了