我刚刚写了一个文件:
real*8 :: vol_cel
real*8, dimension(256,256,256) :: dense
[... some operations]
open(unit=8,file=fname,form="unformatted")
write(8)dense(:,:,:)/vol_cell
close(8)
我的代码在Matlab中阅读:
fid = fopen(fname,'r');
mesh_raw = fread(fid,256*256*256,'double');
fclose(fid);
最小值和最大值清楚地表明它没有正确读取它(Min是0,max是一个大的正实数* 8)。
min =
3.3622e+38
max =
-3.3661e+38
我需要在Matlab中设置什么精度才能在未格式化的Fortran文件中读取它?
一个有点相关的问题:我使用的这个Matlab代码读取二进制文件OK但不是未格式化的文件。虽然我使用gfortran在Mac OSX上生成这些新数据。它无法识别form =“binary”,所以我无法这样做。我是否需要添加一些库或这是一个字节序问题?
=====进展=====
好的进展。我只是写出x值(列向量)而不是我的ndim * ndim * ndim矩阵:
open(unit=8,file=fnamex,form="unformatted")
write(8)x0
close(8)
然后Matlab读到:
fid = fopen(nfilename,'r');
hr3=fread(fid, 1, 'int32');
x0 = fread(fid,Ntot,'float32');
hr4=fread(fid, 1, 'int32');
fclose(fid);
这是有效的。然后我尝试了原始的ndim ** 3矩阵,我试着阅读:
fid = fopen(nfilename,'r');
hr3=fread(fid, 1, 'int32');
mesh_raw = fread(fid,ndim*ndim*ndim,'float32');
hr4=fread(fid, 1, 'int32');
fclose(fid);
但那给了我垃圾。也许在这里:
real*4, dimension(:), allocatable :: x0
real*8, dimension(256,256,256) :: dense
我需要更改:mesh_raw = fread(fid,ndim * ndim * ndim,'float32');确保它正在读取真正的* 8?那会是什么?当然只是使用'真正的* 8'逐字应该工作?我的意思是x矢量工作的'真正的* 4'。我的意思是它读取“密集”但最小/最大/平均值是错误的。
答案 0 :(得分:1)
这很可能是一个endian问题,因为粗略有序的猜测让我更加合理。我不确定解决方案是什么,所以我将给你3个可能的解决方案,其中一个应该解决问题。这取决于您的源文件。
诀窍就是将fopen
语句更改为以下之一:
fid = fopen(fname,'rn'); %Native format (Default usually)
fid = fopen(fname,'rl'); %Little Endian
fid = fopen(fname,'rb'); %Big Endian
答案 1 :(得分:1)
您的Fortran代码显示您正在编写所谓的无格式顺序文件。这是一种基于记录的文件格式。典型的实现(Fortran编译器/平台特定)是为编译器将附加记录结构信息写入文件 - 通常(包括gfortran)记录长度写在每条记录的开头和结尾。您的原始Matlab代码似乎没有考虑到这一点。
Fortran 2003引入了流访问(将ACCESS='STREAM'
说明符添加到OPEN语句中)。 gfortran支持此功能,FORM ='BINARY'是某些编译器的非标准同义词。使用流访问创建的未格式化文件没有记录结构 - 它是类似于C流的字节流。这可能更适合你。
答案 2 :(得分:0)
fid = fopen(nfilename,'r');
hr3=fread(fid, 1, 'int32');
mesh_raw = fread(fid,ndim*ndim*ndim,'float32');
hr4=fread(fid, 1, 'int32');
fclose(fid);
这是正确的,除非你在fortran写的是真正的* 8,你需要
mesh_raw = fread(fid,ndim*ndim*ndim,'double');