1

我刚刚写了一个文件:

 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);

最小值和最大值清楚地表明它没有正确读取(最小值为 0,最大值为较大的正实数 *8)。

min =
   3.3622e+38
max =
  -3.3661e+38

我需要在 Matlab 中设置什么精度才能使其在未格式化的 Fortran 文件中读取?

一个有点相关的问题:我正在使用的这个 Matlab 代码可以读取二进制文件,但不能读取未格式化的文件。虽然我正在使用 gfortran 在我的 Mac OSX 上生成这些新数据。它不识别 form="binary" 所以我不能那样做。我需要添加一些库还是这是一个字节序问题?

===== 进展 =====

好的进展。而不是我的 ndim*ndim*ndim 矩阵,我只是这样写出 x 值(列向量):

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?那会是什么?当然只是逐字使用'real * 8'应该有效吗?我的意思是 x 矢量作品的“真实* 4”。我的意思是它读作“密集”,但最小值/最大值/平均值是错误的。

4

3 回答 3

1

这很可能是一个字节序问题,因为粗略的有序猜测对我来说是一个更合理的数字。我不确定解决方案是什么,所以我将为您提供 3 个可能的解决方案,其中一个应该可以解决问题。这取决于您的源文件。

诀窍是将fopen语句更改为以下之一:

fid = fopen(fname,'rn');  %Native format (Default usually)
fid = fopen(fname,'rl');  %Little Endian
fid = fopen(fname,'rb');  %Big Endian
于 2012-11-28T00:02:09.350 回答
1

您的 Fortran 代码向您展示了如何编写所谓的无格式顺序文件。这是一种基于记录的文件格式。典型的实现(Fortran 编译器/平台特定)是编译器将附加记录结构信息写入文件 - 通常(包括 gfortran)记录长度写在每个记录的开头和结尾。您的原始 Matlab 代码似乎没有考虑到这一点。

Fortran 2003 引入了流访问(将说明ACCESS='STREAM'符添加到 OPEN 语句)。gfortran 支持此功能, FORM='BINARY' 在某些编译器上是非标准同义词。使用流访问创建的未格式化文件没有记录结构 - 它是类似于 C 流的字节流。这可能更适合您。

于 2012-11-29T01:09:59.423 回答
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 中编写 real*8,你需要有

mesh_raw = fread(fid,ndim*ndim*ndim,'double');
于 2014-02-28T16:34:11.383 回答