找回密码
 注册
Simdroid-非首页
查看: 236|回复: 6

[命令/FISH] [原创]读取Flac3D二进制文件

[复制链接]
发表于 2013-10-22 20:55:42 | 显示全部楼层 |阅读模式 来自 陕西西安
本帖最后由 echowasd 于 2013-10-22 21:00 编辑

Flac3D计算时常需要提取数据并写出,以便后处理使用。提取数据的方法主要有两种。
(1) 打开记录(set log on),然后打印变量(print nvar),则变量会记录在flac3d.log的文件中,用记事本或Excel编辑处理即可。
(2) 采用文件函数,打开文件(open()),写变量(write()),关闭(close())。
第2种方法数据的提取完全用fish语言来控制,更适合自动化处理。写文件的方式有两种,一种是写文本文件(ASCII),另一种是写二进制文件(BINARY)。
(1) ASCII方式写出文本文件可以直接用记事本打开查看编辑,但缺点是只能写出字符类型(string)的数据,当要写整形(integer)和浮点型(float)的数据时必须要类型转换,比如disp(1)=string(123.456),然后才能write(disp,1)写出。在类型转换的过程中会出现精度降低的问题,string(123.456)得出的结果是'1.2E2'(采用科学计数法),后面的3.456就给丢失了。
(2) BINARY方式则不需要类型转换,可直接写出字符、整数和浮点数,不存在精度降低的问题,但是Flac3D没有提供直接打开此二进制文件的程序,数据存储形式也无从可知。
近日尝试采用C#读Flac3D写出的二进制文件,并找出数据存储的规律。经过一番尝试,发现规律:
文件开头4个字节为描述,无用,直接跳过,之后的数据排列规律为“类型[字节数]数据”,其中“类型”为1、2、3的任一数字(1表示整型,2表示浮点型,3表示字符型);“字节数”是可选的,因为整形占4字节,浮点型占8字节,只有字符类型才需要设定字节数。所以读此二进制文件的流程为:
(1)从二进制流的第4位开始,先读4个字节(ReadInt32)得数据类型dataType;
(2)若dataType==1(整形),则接着继续读4个字节(ReadInt32)得到数据;若dataType==2(浮点型),则读8个字节(ReadDouble)得数据;若dataType==3(字符型),则需要读4个字节得到数据的字节数num,接着读num个字节ReadChars(num)得数据;最后写出为ASCII数据;
(3)重复“读类型——[读字节数]——读数据——写出ASCII数据”的过程,直到读完二进制流。
王 刚 2013年10月22日
例子
  
flac3d.txt文件,分别定义整形、浮点型和字符型三个数组并赋值,以追加的方式写入“out.flc”文件中。
  
new
  
def para
  
         len  = 10
  
         IO_READ  = 0
  
         IO_WRITE  = 1
  
         IO_APPEND  = 2
  
         IO_BINARY  = 0
  
         IO_ASCII  = 1
  
end
  
para
  
def tst
  
         ;  integer
  
         array  ss(len)
  
         loop  i(1,len)
  
                   ss(i)=i
  
         endloop
  
end
  
tst
  
def tst3
  
         ;  double
  
         array  dd(len)
  
         loop  i(1,len)
  
                   dd(i)=0.05*i
  
         endloop
  
end
  
tst3
  
def tst5
  
         ;  char
  
         array  cc(len)
  
         loop  i(1,len)
  
                   cc(i)  = 'char' + string(i)
  
         endloop
  
end
  
tst5
  
def tst7
  
         statue  = open('out.flc',IO_WRITE,IO_BINARY)
  
         statue  = write(dd,len)
  
         statue  = close
  
         statue  = open('out.flc',IO_APPEND,IO_BINARY)
  
         statue  = write(ss,len)
  
         statue  = close
  
         statue  = open('out.flc',IO_APPEND,IO_BINARY)
  
         statue  = write(cc,len)
  
         statue  = close
  
end
  
tst7
打开Flac3D,call flac3d.txt,生成out.flc文件,outflc内容应该为:0.05~0.5,1~10,char1~char10。
  
C#主要函数,read()
  
static void read()
  
{
  
         //  1 = int
  
         //  2 = double
  
         //  3 = char
  
  
         string  filePath = "out.flc";
  
         string  outFile = "out-ascii.txt";
  
  
         FileStream  fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  
         BinaryReader  br = new BinaryReader(fs);
  
         FileStream  fs2 = new FileStream(outFile, FileMode.Create, FileAccess.Write);
  
         StreamWriter  sw = new StreamWriter(fs2);
  
  
         br.BaseStream.Position  = 4;
  
         long  len = fs.Length;
  
         long  pos = 4;
  
  
         while  (pos < len)
  
         {
  
                   int  flag = br.ReadInt32();
  
                   pos  += 4;
  
                   switch  (flag)
  
                   {
  
                            case  1:
  
                                     int  ivalue = br.ReadInt32();
  
                                     sw.WriteLine(ivalue);
  
                                     pos  += 4;
  
                                     break;
  
                            case  2:
  
                                     double  dvalue = br.ReadDouble();
  
                                     sw.WriteLine(dvalue);
  
                                     pos  += 8;
  
                                     break;
  
                            case  3:
  
                                     int  num = br.ReadInt32();
  
                                     num  += 4 - num % 4;
  
                                     char[]  ch = br.ReadChars(num);
  
                                     sw.WriteLine(ch);
  
                                     pos  += 4 + num;
  
                                     break;
  
                   }
  
                   br.BaseStream.Position  = pos;
  
         }
  
         br.Close();
  
         sw.Close();
  
         fs.Dispose();
  
         fs2.Dispose();
  
}
编译运行后生成一个"out-ascii.txt"文件,即我们想要得到的Flac3D二进制写出文件中的数据,无精度丢失问题:
  
out-ascii.txt  
  
0.05
  
0.1
  
0.15
  
0.2
  
0.25
  
0.3
  
0.35
  
0.4
  
0.45
  
0.5
  
1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
char1   
  
char2   
  
char3   
  
char4   
  
char5   
  
char6   
  
char7   
  
char8   
  
char9   
  
char10   
  


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
发表于 2013-12-14 15:25:12 | 显示全部楼层 来自 山东济南
Simdroid开发平台
不错,学习学习了
回复 不支持

使用道具 举报

发表于 2013-12-15 23:45:30 | 显示全部楼层 来自 辽宁沈阳
采用文本文件ASCII写入方式,如果是百位数如123.456,结果为1.2346e+002;如果是千位数如1223.456,结果是 1.2235e+003 ,数据再大的话,后面的小数点影响就很小了;小数据他后面精确的小数点位数也多,比如 1.223456,写入结果是1.2235e+000 ,可精确到第四位,这种精度完全能满足科研或是工程要求,楼主花时间与精力在这个方面觉得好钢没有用在刀刃上。
回复 不支持

使用道具 举报

发表于 2014-10-18 06:49:51 | 显示全部楼层 来自 山东济南
谢谢提供分享
回复 不支持

使用道具 举报

发表于 2014-10-19 01:37:04 | 显示全部楼层 来自 北美地区
楼主的工作还是很有意义的
回复 不支持

使用道具 举报

 楼主| 发表于 2014-10-19 15:15:05 | 显示全部楼层 来自 四川成都
zpp080425 发表于 2013-12-15 23:45
采用文本文件ASCII写入方式,如果是百位数如123.456,结果为1.2346e+002;如果是千位数如1223.456,结果是  ...

还好吧,用了一下午时间,Itasca没公布其二进制文件的数据结构,当时搞这个主要是好奇心驱使。
回复 不支持

使用道具 举报

发表于 2016-4-19 08:23:55 | 显示全部楼层 来自 湖北武汉
好东西,值得学习!
回复 不支持

使用道具 举报

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

本版积分规则

Simapps系列直播

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-10-4 12:33 , Processed in 0.037255 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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