本帖最后由 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
|
|